runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "isa",
  "category": "introspection",
  "keywords": [
    "isa",
    "type checking",
    "class comparison",
    "numeric category",
    "gpuArray"
  ],
  "summary": "Test whether a value belongs to a specified MATLAB class or abstract category.",
  "references": [
    "https://www.mathworks.com/help/matlab/ref/isa.html"
  ],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [],
    "broadcasting": "none",
    "notes": "Returns host logical scalars and inspects gpuArray metadata without launching kernels."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 2,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::introspection::isa::tests",
    "integration": "builtins::introspection::isa::tests::isa_gpu_arrays_treat_metadata_correctly"
  },
  "description": "`isa(x, T)` returns logical `true` when the value `x` is a member of the MATLAB class or abstract category identified by `T`. Use it to branch on numeric vs integer data, handle objects, GPU arrays, function handles, and user-defined classes.",
  "behaviors": [
    "Exact class names (such as `\"double\"`, `\"cell\"`, `\"struct\"`, `\"event.listener\"`) match the value’s dynamic class. Comparisons are case-insensitive.",
    "Abstract categories (`\"numeric\"`, `\"float\"`, `\"integer\"`, `\"handle\"`, `\"function_handle\"`, `\"gpuArray\"`, `\"listener\"`) mirror MATLAB’s grouping rules.",
    "Logical scalars, logical arrays, and logical gpuArray masks satisfy `\"logical\"` and do not register as `\"numeric\"`. RunMat consults handle metadata rather than downloading device buffers.",
    "Handle inheritance is respected: if a class derives from `handle`, `isa(obj, \"handle\")` returns `true` even when `class(obj)` reports a subclass name.",
    "`isa` accepts either a string scalar or a character row vector as the class designator.",
    "gpuArray inputs never need to be gathered; RunMat checks residency metadata to answer the query."
  ],
  "examples": [
    {
      "description": "Checking whether a scalar is double precision",
      "input": "tf = isa(42, \"double\")",
      "output": "tf = logical(1)"
    },
    {
      "description": "Testing numeric arrays against the numeric category",
      "input": "A = rand(3, 4);\nis_numeric = isa(A, \"numeric\");\nis_integer = isa(A, \"integer\")",
      "output": "is_numeric = logical(1)\nis_integer = logical(0)"
    },
    {
      "description": "Confirming that gpuArray data counts as numeric",
      "input": "G = gpuArray(rand(1024, 1024));\ntf_numeric = isa(G, \"numeric\");\ntf_double = isa(G, \"double\");   % false — the class reports gpuArray",
      "output": "tf_numeric = logical(1)\ntf_double = logical(0)"
    },
    {
      "description": "Determining whether a GPU mask is logical",
      "input": "G = gpuArray(rand(5) > 0.5);\nis_mask = isa(G, \"logical\");\nis_numeric = isa(G, \"numeric\")",
      "output": "is_mask = logical(1)\nis_numeric = logical(0)"
    },
    {
      "description": "Validating handle subclasses",
      "input": "pt = pkg.TestHandle();          % derives from handle\ntf_handle = isa(pt, \"handle\");\ntf_exact = isa(pt, \"pkg.TestHandle\")",
      "output": "tf_handle = logical(1)\ntf_exact = logical(1)"
    },
    {
      "description": "Comparing string scalars and character vectors",
      "input": "s = \"RunMat\";\nc = 'RunMat';\ntf_string = isa(s, \"string\");\ntf_char = isa(c, \"char\")",
      "output": "tf_string = logical(1)\ntf_char = logical(1)"
    },
    {
      "description": "Detecting function handles and listeners",
      "input": "fh = @sin;\ntf_handle = isa(fh, \"function_handle\");\nlst = addlistener(TestSource, \"Changed\", @disp);\ntf_listener = isa(lst, \"listener\")",
      "output": "tf_handle = logical(1)\ntf_listener = logical(1)"
    }
  ],
  "faqs": [
    {
      "question": "Does `isa` treat gpuArray values as numeric?",
      "answer": "Yes for numeric device arrays. `isa(gpuArray(rand(4)), \"numeric\")` and `isa(..., \"float\")` return `true`, even though the concrete class is `\"gpuArray\"`. Logical gpuArray masks skip the numeric categories and only satisfy `\"logical\"`. Use `isa(..., \"double\")` when you specifically need host doubles."
    },
    {
      "question": "How do I check for integer types?",
      "answer": "Use the `\"integer\"` category. It matches MATLAB’s native integer classes (`int8`, `uint16`, and so on). For example `isa(int32(5), \"integer\")` returns `true` while `isa(5, \"integer\")` returns `false`."
    },
    {
      "question": "Does `isa` understand handle inheritance?",
      "answer": "Yes. If a class derives from `handle`, then the object passes the `\"handle\"` category check. The builtin walks parent classes registered with RunMat to mirror MATLAB semantics."
    },
    {
      "question": "What kinds of strings can I pass as the type name?",
      "answer": "Provide either a string scalar (double quotes) or a character row vector (single quotes). Multi-row character arrays and string arrays with more than one element throw a descriptive error."
    },
    {
      "question": "How do I detect function handles or anonymous functions?",
      "answer": "Both named function handles and closures pass `isa(value, \"function_handle\")`."
    },
    {
      "question": "Will `isa` gather gpuArray inputs or launch kernels?",
      "answer": "No. The builtin is metadata-only and returns a host logical scalar without copying device buffers."
    },
    {
      "question": "How are listeners treated?",
      "answer": "Event listeners pass both `isa(listener, \"event.listener\")` and the compatibility alias `isa(listener, \"listener\")`. They also satisfy the `\"handle\"` category."
    },
    {
      "question": "Does `isa` differentiate between string and char arrays?",
      "answer": "Yes. String scalars pass `\"string\"` while character arrays pass `\"char\"`. They are not interchangeable."
    },
    {
      "question": "Can I use `isa` to test meta-class values?",
      "answer": "Yes. Meta-class references created with `classref` return `true` for `\"meta.class\"`."
    }
  ],
  "links": [
    {
      "label": "`class`",
      "url": "./class"
    },
    {
      "label": "`isnumeric`",
      "url": "./isnumeric"
    },
    {
      "label": "`islogical`",
      "url": "./islogical"
    },
    {
      "label": "`gpuArray`",
      "url": "./gpuarray"
    },
    {
      "label": "`gather`",
      "url": "./gather"
    },
    {
      "label": "ischar",
      "url": "./ischar"
    },
    {
      "label": "isstring",
      "url": "./isstring"
    },
    {
      "label": "which",
      "url": "./which"
    },
    {
      "label": "who",
      "url": "./who"
    },
    {
      "label": "whos",
      "url": "./whos"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/introspection/isa.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/introspection/isa.rs"
  },
  "gpu_residency": "You usually do NOT need to call `gpuArray` yourself in RunMat (unlike MATLAB).\n\nIn RunMat, the fusion planner keeps residency on GPU in branches of fused expressions. As such, when you call `isa` on a gpuArray result, the planner preserves the device buffer and `isa` answers the query using metadata only.\n\nTo preserve backwards compatibility with MathWorks MATLAB, and for when you want to explicitly bootstrap GPU residency, you can call `gpuArray` explicitly to move data to the GPU if you want to be explicit about the residency.\n\nSince MathWorks MATLAB does not have a fusion planner, and they kept their parallel execution toolbox separate from the core language, as their toolbox is a separate commercial product, MathWorks MATLAB users need to call `gpuArray` to move data to the GPU manually whereas RunMat users can rely on the fusion planner to keep data on the GPU automatically.",
  "gpu_behavior": [
    "`isa` never launches GPU kernels. For gpuArray inputs RunMat inspects the `GpuTensorHandle` metadata to identify the device array and satisfy category checks such as `\"numeric\"` and `\"gpuArray\"`. Because the builtin only returns a host logical scalar it does not participate in fusion, and providers do not need to expose additional hooks."
  ]
}