Null when eindir is not linked. Does not take ownership of the objective or the cache.
189 {
190#ifndef WITH_EINDIR
191 (void)objective;
192 (void)cached;
193 return nullptr;
194#else
196 return nullptr;
197 }
198 auto state = std::make_unique<State>();
199 state->objective = objective;
200 state->cached = cached;
202 const double inf = std::numeric_limits<double>::infinity();
203 state->low.assign(dim, -inf);
204 state->high.assign(dim, inf);
206 actual.producer_id = "eon.objective";
207 state->schema = actual.schema_id;
208 state->producer = actual.producer_id;
209 state->length_unit = actual.length_unit;
210 state->energy_unit = actual.energy_unit;
211 state->desc.schema_id = state->schema.c_str();
212 state->desc.producer_id = state->producer.c_str();
213 state->desc.length_unit = state->length_unit.c_str();
214 state->desc.energy_unit = state->energy_unit.c_str();
215 state->desc.energy_sign = actual.energy_sign;
216 state->desc.gradient_sign = actual.gradient_sign;
217 state->desc.operations = actual.operations;
218 state->desc.tensor_device_type = actual.tensor_device_type;
219 state->desc.tensor_dtype_code = actual.tensor_dtype_code;
220 state->desc.tensor_dtype_bits =
221 static_cast<std::uint8_t>(actual.tensor_dtype_bits);
222 state->desc.tensor_dtype_lanes =
223 static_cast<std::uint8_t>(actual.tensor_dtype_lanes);
224 state->desc.tensor_layout = actual.tensor_layout;
225 state->desc.callback_lifetime = actual.callback_lifetime;
226 state->obj.dim = dim;
227 state->obj.low = state->low.data();
228 state->obj.high = state->high.data();
229 state->obj.eval_fn = eval_cb;
230 state->obj.grad_fn = grad_cb;
231 state->obj.user_data = state.get();
232 state->obj.free_fn = nullptr;
233 state->obj.descriptor = &state->desc;
235 throw std::runtime_error("eOn eindir objective descriptor was rejected");
236 }
237 const auto stamp = eindir_core_abi_stamp();
238 if (eindir_core_abi_compatible(&stamp) == 0 ||
240 throw std::runtime_error("incompatible eindir ABI stamp");
241 }
242 if (eindir_objective_has_grad(&state->obj) == 0) {
243 throw std::runtime_error("eindir objective has no gradient");
244 }
245 eindir_objective_descriptor_t required_desc = state->desc;
246 required_desc.producer_id = "";
247 if (eindir_objective_descriptor_compatible(&state->desc, &required_desc) ==
248 0) {
249 const char *err = eindir_last_error();
250 throw std::runtime_error(err != nullptr ? err
251 : "eindir descriptor mismatch");
252 }
253 const auto xts = xts_abi_stamp();
254 provenance_slot() =
255 std::format("xts-{}.{}.{}+eindir-{}.{}-layout-{}", xts.abi_major,
256 xts.abi_minor, xts.layout_revision, stamp.abi_major,
257 stamp.abi_minor, stamp.objective_layout);
258 return state.release();
259#endif
260}
virtual int degreesOfFreedom()=0
bool abi_accepts_gradient(std::uint32_t major, std::uint32_t expected_major, std::uint64_t features)
Major must match and the gradient feature bit must be set.
View eon_requirement()
What an eOn minimization may consume: eV, angstrom, analytic forces.
bool compatible(const View &actual, const View &required)
Nonzero when actual satisfies required. Schema id is never a wildcard.