Class: Kumi::FunctionRegistry::Instance
- Inherits:
-
Object
- Object
- Kumi::FunctionRegistry::Instance
- Defined in:
- lib/kumi/function_registry.rb
Overview
A loaded, queryable registry. Construct via FunctionRegistry.load.
Instance Method Summary collapse
-
#function(id) ⇒ Object
The Function record for an alias or id.
-
#function?(id) ⇒ Boolean
Non-raising existence check.
- #impl_for(kernel_id) ⇒ Object
-
#initialize(functions_by_id, kernels_by_key) ⇒ Instance
constructor
A new instance of Instance.
-
#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.
- #kernel_id_for(id, target:) ⇒ Object
- #kernel_identity_for(id, dtype:, target:) ⇒ Object
- #reduce?(id) ⇒ Boolean
-
#registry_ref ⇒ Object
Stable content hash of the loaded functions + kernels, used to detect drift between a compiled artifact and the registry it was built against.
-
#resolve(alias_or_id, arg_types) ⇒ Object
Type-aware overload resolution: pick the function id whose parameter constraints best match the given argument types.
-
#resolve_id(id) ⇒ Object
Resolve an alias or id to its canonical function id.
- #select?(id) ⇒ Boolean
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.
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
92 |
# File 'lib/kumi/function_registry.rb', line 92 def reduce?(id) = function(id).reduce? |
#registry_ref ⇒ Object
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
91 |
# File 'lib/kumi/function_registry.rb', line 91 def select?(id) = resolve_id(id) == SELECT_ID |