MCPcopy Create free account
hub / github.com/ciphermodelabs/ciphercore / instantiate

Method instantiate

ciphercore-base/src/ops/goldschmidt_division.rs:60–134  ·  view source on GitHub ↗
(&self, context: Context, arguments_types: Vec<Type>)

Source from the content-addressed store, hash-verified

58#[typetag::serde]
59impl CustomOperationBody for GoldschmidtDivision {
60 fn instantiate(&self, context: Context, arguments_types: Vec<Type>) -> Result<Graph> {
61 if arguments_types.len() != 2 && arguments_types.len() != 3 {
62 return Err(runtime_error!(
63 "Invalid number of arguments for GoldschmidtDivision, given {}, expected 2 or 3",
64 arguments_types.len()
65 ));
66 }
67
68 let dividend_type = arguments_types[0].clone();
69 let divisor_type = arguments_types[1].clone();
70 if dividend_type.get_scalar_type() != divisor_type.get_scalar_type() {
71 return Err(runtime_error!(
72 "Invalid scalar types for GoldschmidtDivision: dividend scalr type {} and divisor scalar type {} must be the same",
73 dividend_type.get_scalar_type(),
74 divisor_type.get_scalar_type()
75 ));
76 }
77 if !divisor_type.is_scalar() && !divisor_type.is_array() {
78 return Err(runtime_error!(
79 "Divisor in GoldschmidtDivision must be a scalar or an array"
80 ));
81 }
82 if !dividend_type.is_scalar() && !dividend_type.is_array() {
83 return Err(runtime_error!(
84 "Dividend in GoldschmidtDivision must be a scalar or an array"
85 ));
86 }
87
88 let sc = dividend_type.get_scalar_type();
89 if sc.size_in_bits() < 64 {
90 return Err(runtime_error!(
91 "Divisor in GoldshmidtDivision supported only for 64-bit+ types: INT64, UINT64, INT128, UINT128"
92 ));
93 }
94 let has_initial_approximation = arguments_types.len() == 3;
95 if has_initial_approximation {
96 let initial_approximation_t = arguments_types[2].clone();
97 if initial_approximation_t != divisor_type {
98 return Err(runtime_error!(
99 "Divisor and initial approximation must have the same type."
100 ));
101 }
102 }
103
104 let g_initial_approximation =
105 inverse_initial_approximation(&context, divisor_type.clone(), self.denominator_cap_2k)?;
106 let g = context.create_graph()?;
107 let dividend = g.input(dividend_type)?;
108 let divisor = g.input(divisor_type.clone())?;
109 let approximation = if has_initial_approximation {
110 g.input(divisor_type)?
111 } else if self.denominator_cap_2k == 0 {
112 g.ones(divisor_type)?
113 } else {
114 g.call(g_initial_approximation, vec![divisor.clone()])?
115 };
116 // Now, we do Goldschmidt approximation for computing 1 / x,
117 // The formula for Goldschmidt division iteration is

Callers

nothing calls this directly

Calls 15

constant_scalarFunction · 0.85
multiply_fixed_pointFunction · 0.85
cloneMethod · 0.80
is_scalarMethod · 0.80
is_arrayMethod · 0.80
onesMethod · 0.80
get_scalar_typeMethod · 0.45
size_in_bitsMethod · 0.45
create_graphMethod · 0.45
inputMethod · 0.45
callMethod · 0.45

Tested by

no test coverage detected