Class: Kumi::FunctionRegistry::Instance

Inherits:
Object
  • Object
show all
Defined in:
lib/kumi/function_registry.rb

Overview

A loaded, queryable registry. Construct via FunctionRegistry.load.

Instance Method Summary collapse

Constructor Details

#initialize(functions_by_id, kernels_by_key) ⇒ Instance

Returns a new instance of Instance.



49
50
51
52
53
54
55
# File 'lib/kumi/function_registry.rb', line 49

def initialize(functions_by_id, kernels_by_key)
  @functions = functions_by_id                         # "core.mul" => Function<...>
  @alias     = build_alias(@functions)                 # "count" => "agg.count"
  @overload_resolver = Core::Functions::OverloadResolver.new(@functions)
  @kernels   = kernels_by_key                          # [fn_id, target_sym] => Kernel
  @by_id     = @kernels.values.to_h { |k| [k.id, k] }
end

Instance Method Details

#function(id) ⇒ Object

The Function record for an alias or id. Assumes the function exists (it has passed validation); a miss is an internal bug, not a user error.



61
62
63
# File 'lib/kumi/function_registry.rb', line 61

def function(id)
  @functions.fetch(resolve_id(id))
end

#function?(id) ⇒ Boolean

Non-raising existence check. Validation uses this to report an unknown function as a located user error before any resolve_* is attempted.

Returns:

  • (Boolean)


67
68
69
70
# File 'lib/kumi/function_registry.rb', line 67

def function?(id)
  s = id.to_s
  @functions.key?(s) || @alias.key?(s)
end

#impl_for(kernel_id) ⇒ Object



115
116
117
# File 'lib/kumi/function_registry.rb', line 115

def impl_for(kernel_id)
  (@by_id[kernel_id] or raise Kumi::Core::Errors::CompilerBug, "unknown kernel #{kernel_id}").impl
end

#kernel_for(id, target:) ⇒ Object

—- kernels ———————————————————— A function that resolved must have a backend kernel; a miss here is an invariant violation (CompilerBug), never a user error.



98
99
100
101
# File 'lib/kumi/function_registry.rb', line 98

def kernel_for(id, target:)
  fid = resolve_id(id)
  @kernels[[fid, target.to_sym]] or raise Kumi::Core::Errors::CompilerBug, "no kernel for #{fid} on #{target}"
end

#kernel_id_for(id, target:) ⇒ Object



103
104
105
# File 'lib/kumi/function_registry.rb', line 103

def kernel_id_for(id, target:)
  kernel_for(id, target: target).id
end

#kernel_identity_for(id, dtype:, target:) ⇒ Object



107
108
109
110
111
112
113
# File 'lib/kumi/function_registry.rb', line 107

def kernel_identity_for(id, dtype:, target:)
  kernel = kernel_for(id, target: target)
  map = kernel.identity or raise Kumi::Core::Errors::CompilerBug, "no identity for #{kernel.fn_id} on #{target}"

  map[dtype.to_s] || map["any"] or
    raise Kumi::Core::Errors::CompilerBug, "no identity for dtype #{dtype} on #{kernel.fn_id}"
end

#reduce?(id) ⇒ Boolean

Returns:

  • (Boolean)


92
# File 'lib/kumi/function_registry.rb', line 92

def reduce?(id) = function(id).reduce?

#registry_refObject

Stable content hash of the loaded functions + kernels, used to detect drift between a compiled artifact and the registry it was built against.



123
124
125
126
127
128
129
130
131
# File 'lib/kumi/function_registry.rb', line 123

def registry_ref
  kernels = @by_id.values
                  .map { |k| { "id" => k.id, "fn" => k.fn_id, "target" => k.target.to_s, "impl" => k.impl } }
                  .sort_by { _1["id"] }
  functions = @functions.transform_values do |f|
    { "kind" => f.kind.to_s, "aliases" => f.aliases, "params" => f.params }
  end
  "sha256:#{Digest::SHA256.hexdigest(JSON.generate(kernels: kernels, functions: functions))}"
end

#resolve(alias_or_id, arg_types) ⇒ Object

Type-aware overload resolution: pick the function id whose parameter constraints best match the given argument types. Raises OverloadResolver::ResolutionError on a type/arity mismatch, which the dimensional analyzer turns into a located user error.



87
88
89
# File 'lib/kumi/function_registry.rb', line 87

def resolve(alias_or_id, arg_types)
  @overload_resolver.resolve(alias_or_id, arg_types)
end

#resolve_id(id) ⇒ Object

Resolve an alias or id to its canonical function id. Assumes existence (validation runs first); an unresolved id here is a CompilerBug.



74
75
76
77
78
79
80
81
# File 'lib/kumi/function_registry.rb', line 74

def resolve_id(id)
  s = id.to_s
  return s if @functions.key?(s)

  @alias.fetch(s) do
    raise Kumi::Core::Errors::CompilerBug, "unknown function #{id} (should be rejected during validation)"
  end
end

#select?(id) ⇒ Boolean

Returns:

  • (Boolean)


91
# File 'lib/kumi/function_registry.rb', line 91

def select?(id) = resolve_id(id) == SELECT_ID