Module: Kumi::FunctionRegistry::Loader
- Defined in:
- lib/kumi/function_registry/loader.rb
Overview
Reads the function/kernel YAML into the registry’s record structs and compiles each function’s dtype rule. Every failure here is a malformed registry data file, not user input, so they surface as CompilerBug.
Constant Summary collapse
- Bug =
Kumi::Core::Errors::CompilerBug
Class Method Summary collapse
-
.build_dtype_rule_from_yaml(spec) ⇒ Object
Build the result-type rule for a function from its YAML ‘dtype:` spec.
- .fetch_param(spec, key) ⇒ Object
-
.load_functions(dir, func_struct) ⇒ Object
{ “core.mul” => Function(id: “core.mul”, kind: :elementwise, params: […]) }.
-
.load_kernels(root, kernel_struct) ⇒ Object
{ [“core.mul”, :ruby] => Kernel }.
- .symbolize_keys(hash) ⇒ Object
Class Method Details
.build_dtype_rule_from_yaml(spec) ⇒ Object
Build the result-type rule for a function from its YAML ‘dtype:` spec. The spec is always a structured hash with a `rule` key naming one of the rule builders in Types::DtypeRule.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/kumi/function_registry/loader.rb', line 18 def build_dtype_rule_from_yaml(spec) raise Bug, "dtype spec must be a hash with a 'rule' key, got #{spec.inspect}" unless spec.is_a?(Hash) rules = Kumi::Core::Types::DtypeRule rule_type = spec.fetch("rule") { raise Bug, "dtype hash requires 'rule' key" } case rule_type when "same_as" rules.same_as(fetch_param(spec, "param")) when "promote" params = spec.fetch("params") { raise Bug, "promote rule requires 'params' key" } rules.promote(*Array(params).map(&:to_sym)) when "element_of" rules.element_of(fetch_param(spec, "param")) when "unify" rules.unify(fetch_param(spec, "param1"), fetch_param(spec, "param2")) when "scalar" kind = spec.fetch("kind") { raise Bug, "scalar rule requires 'kind' key" }.to_sym raise Bug, "scalar rule has unknown kind: #{kind}" unless Kumi::Core::Types::Registry.kind?(kind) rules.scalar(kind) else raise Bug, "unknown dtype rule: #{rule_type}" end end |
.fetch_param(spec, key) ⇒ Object
44 45 46 |
# File 'lib/kumi/function_registry/loader.rb', line 44 def fetch_param(spec, key) spec.fetch(key) { raise Bug, "#{spec['rule']} rule requires '#{key}' key" }.to_sym end |
.load_functions(dir, func_struct) ⇒ Object
{ “core.mul” => Function(id: “core.mul”, kind: :elementwise, params: […]) }
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/kumi/function_registry/loader.rb', line 49 def load_functions(dir, func_struct) files = Dir.glob(File.join(dir, "**", "*.y{a,}ml")) funcs = files.flat_map { |p| (YAML.load_file(p) || {}).fetch("functions", []) } funcs.each_with_object({}) do |h, acc| f = func_struct.new( id: h.fetch("id").to_s, kind: h.fetch("kind").to_s.to_sym, aliases: Array(h["aliases"]).map!(&:to_s), params: h.fetch("params"), dtype: h["dtype"], expand: h["expand"], options: symbolize_keys(h["options"] || {}), folding_class_method: h["folding_class_method"], reduction_strategy: h["reduction_strategy"]&.to_sym ) raise Bug, "duplicate function id `#{f.id}`" if acc.key?(f.id) acc[f.id] = f end end |
.load_kernels(root, kernel_struct) ⇒ Object
{ [“core.mul”, :ruby] => Kernel }
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/kumi/function_registry/loader.rb', line 75 def load_kernels(root, kernel_struct) targets = Dir.glob(File.join(root, "*")).select { |p| File.directory?(p) }.map { |p| File.basename(p).to_sym } out = {} targets.each do |t| Dir.glob(File.join(root, t.to_s, "**", "*.y{a,}ml")).each do |p| (YAML.load_file(p) || {}).fetch("kernels", []).each do |h| k = kernel_struct.new( id: h.fetch("id"), fn_id: h.fetch("fn").to_s, target: t, impl: h["impl"], identity: h["identity"], inline: h["inline"], fold_inline: h["fold_inline"] ) key = [k.fn_id, t] raise Bug, "duplicate kernel for #{key}" if out.key?(key) out[key] = k end end end out end |
.symbolize_keys(hash) ⇒ Object
70 71 72 |
# File 'lib/kumi/function_registry/loader.rb', line 70 def symbolize_keys(hash) hash.transform_keys(&:to_sym) end |