defmodule EXGBoost.ArrayInterface do @moduledoc false @typedoc """ The XGBoost C API uses and is moving towards mainly supporting the use of JSON-Encoded NumPy ArrayyInterface format to pass data to and from the C API. This struct is used to represent the ArrayInterface format. If you wish to use the EXGBoost.NIF library directly, this will be the desired format to pass Nx.Tensors to the NIFs. Use of the EXGBoost.NIF library directly is not recommended unless you are familiar with the XGBoost C API and the EXGBoost.NIF library. See https://numpy.org/doc/stable/reference/arrays.interface.html for more information on the ArrayInterface protocol. """ @type t :: %__MODULE__{ typestr: String.t(), shape: tuple(), address: pos_integer(), readonly: boolean(), tensor: Nx.Tensor.t() } @enforce_keys [:typestr, :shape, :address, :readonly] defstruct [ :typestr, :shape, :address, :readonly, :tensor, version: 3 ] defimpl Jason.Encoder do def encode( %{ typestr: typestr, shape: shape, address: address, readonly: readonly, version: version }, opts ) do Jason.Encode.map( %{ typestr: typestr, shape: Tuple.to_list(shape), data: [address, readonly], version: version }, opts ) end end defimpl Inspect do import Inspect.Algebra def inspect( %{ typestr: typestr, shape: shape, address: address, readonly: readonly, version: version }, opts ) do concat([ "#ArrayInterface<", line(), to_doc( %{ typestr: typestr, shape: Tuple.to_list(shape), data: [address, readonly], version: version }, opts ), line(), ">" ]) end end @doc """ This function is used to convert Nx.Tensors to the ArrayInterface format. Example: iex> EXGBoost.array_interface(Nx.tensor([[1,2,3],[4,5,6]])) #ArrayInterface< %{data: [4418559984, true], shape: [2, 3], typestr: " " raise ArgumentError, "Invalid tensor type -- #{inspect(t_type)} not supported by EXGBoost" {tensor_type, type_width} -> "<#{Atom.to_string(tensor_type)}#{div(type_width, 8)}" end tensor_addr = EXGBoost.NIF.get_binary_address(Nx.to_binary(tensor)) |> EXGBoost.Internal.unwrap!() %__MODULE__{ typestr: type_char, shape: Nx.shape(tensor), address: tensor_addr, readonly: true, tensor: tensor } end end