Packages
snakepit
0.8.4
0.13.0
0.12.0
0.11.1
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
High-performance pooler and session manager for external language integrations. Supports Python, Node.js, Ruby, and more with gRPC streaming, session management, and production-ready process cleanup.
Current section
Files
Jump to
Current section
Files
lib/snakepit/error/shape.ex
defmodule Snakepit.Error.ShapeMismatch do
@moduledoc """
Shape mismatch error for tensor operations.
Contains detailed information about the shape mismatch including
which dimension differs and what the expected vs actual values were.
"""
defexception [
:expected,
:got,
:dimension,
:expected_dim,
:got_dim,
:operation,
:message
]
@type t :: %__MODULE__{
expected: [integer()] | nil,
got: [integer()] | nil,
dimension: non_neg_integer() | nil,
expected_dim: integer() | nil,
got_dim: integer() | nil,
operation: String.t() | nil,
message: String.t()
}
@impl true
def message(%__MODULE__{message: msg}) when is_binary(msg), do: msg
def message(%__MODULE__{} = error) do
build_message(error)
end
defp build_message(%{expected: expected, got: got, operation: op, dimension: dim}) do
base =
if dim do
"Shape mismatch in #{op || "operation"}: dimension #{dim} expected #{inspect(expected)}, got #{inspect(got)}"
else
"Shape mismatch in #{op || "operation"}: expected #{inspect(expected)}, got #{inspect(got)}"
end
base
end
end
defmodule Snakepit.Error.Shape do
@moduledoc """
Shape error creation helpers.
Provides functions for creating detailed shape mismatch errors
with automatic dimension detection and telemetry emission.
"""
alias Snakepit.Error.ShapeMismatch
@doc """
Creates a shape mismatch error.
Automatically detects which dimension differs and emits telemetry.
## Examples
error = Shape.shape_mismatch([3, 224, 224], [3, 256, 256], "conv2d")
"""
@spec shape_mismatch([integer()], [integer()], String.t()) :: ShapeMismatch.t()
def shape_mismatch(expected, got, operation) when is_list(expected) and is_list(got) do
{dimension, expected_dim, got_dim} = find_mismatch(expected, got)
message =
if length(expected) != length(got) do
"Shape mismatch in #{operation}: rank mismatch - expected #{length(expected)} dimensions #{inspect(expected)}, got #{length(got)} dimensions #{inspect(got)}"
else
"Shape mismatch in #{operation}: expected #{inspect(expected)}, got #{inspect(got)}"
end
error = %ShapeMismatch{
expected: expected,
got: got,
dimension: dimension,
expected_dim: expected_dim,
got_dim: got_dim,
operation: operation,
message: message
}
emit_telemetry(error)
error
end
@doc """
Creates a dimension-specific mismatch error.
Use when you know exactly which dimension has the mismatch.
"""
@spec dimension_mismatch(non_neg_integer(), integer(), integer(), String.t()) ::
ShapeMismatch.t()
def dimension_mismatch(dimension, expected_dim, got_dim, operation) do
message =
"Shape mismatch in #{operation}: dimension #{dimension} expected #{expected_dim}, got #{got_dim}"
error = %ShapeMismatch{
expected: nil,
got: nil,
dimension: dimension,
expected_dim: expected_dim,
got_dim: got_dim,
operation: operation,
message: message
}
emit_telemetry(error)
error
end
@doc """
Creates a broadcast error.
Use when shapes cannot be broadcast together.
"""
@spec broadcast_error([integer()], [integer()], String.t()) :: ShapeMismatch.t()
def broadcast_error(shape1, shape2, operation) do
message =
"Cannot broadcast shapes #{inspect(shape1)} and #{inspect(shape2)} in #{operation}"
error = %ShapeMismatch{
expected: shape1,
got: shape2,
dimension: nil,
expected_dim: nil,
got_dim: nil,
operation: operation,
message: message
}
emit_telemetry(error)
error
end
@spec find_mismatch([integer()], [integer()]) ::
{non_neg_integer() | nil, integer() | nil, integer() | nil}
defp find_mismatch(expected, got) do
if length(expected) != length(got) do
{nil, nil, nil}
else
expected
|> Enum.zip(got)
|> Enum.with_index()
|> Enum.find(fn {{e, g}, _idx} -> e != g end)
|> case do
nil -> {nil, nil, nil}
{{e, g}, idx} -> {idx, e, g}
end
end
end
defp emit_telemetry(%ShapeMismatch{} = error) do
:telemetry.execute(
[:snakepit, :error, :shape_mismatch],
%{},
%{
expected: error.expected,
got: error.got,
dimension: error.dimension,
operation: error.operation
}
)
end
end