#ifndef FESA_SRC_FESA_ELEMENTS_HEX8_PAIR_SIMD_H_ #define FESA_SRC_FESA_ELEMENTS_HEX8_PAIR_SIMD_H_ #include namespace fesa::hex8_internal { /// @brief Trivial raw carrier; neither component is normalized or rounded here. struct PacketPair { double high; double low; }; /// @brief Four independent lanes with no executable constructor or operator. struct PairPacket { PacketPair values[4]; }; struct MaterialPacketInput { PairPacket deviatoric_left; PairPacket deviatoric_right; PairPacket shear_left; PairPacket shear_right; PairPacket tensor_left; PairPacket gradient_dot; PairPacket accumulated; PacketPair weight; }; /// @brief One owned trial point/a and four independent b gradients, raw only. struct GeometryPacketInput { PacketPair gradient_a[3]; PacketPair gradient_stress[3][3]; PairPacket gradient_b[3]; PacketPair weight; }; /// @brief Independent raw contractions; accumulator entries remain caller-owned. struct GeometryPacketOutput { PairPacket gradient_dot; PairPacket weighted_geometric; }; using GeometryPacketEvaluator = void (*)(const GeometryPacketInput&, GeometryPacketOutput*); /// @brief Baseline checked zero-start Dot3/ordered j,l Geo9 and weight products. /// @note Lane order is 0..3. Invalid pairs remain invalid for original gates. void EvaluateGeometryPacketScalar(const GeometryPacketInput& input, GeometryPacketOutput* output); /// @brief Evaluates independent b lanes without horizontal reduction. /// @pre The material selector has admitted CPU/OS/current masked FP state. /// @note Keeps original zero-start, product association and j,l Add order. void EvaluateGeometryPacketAvx2(const GeometryPacketInput& input, GeometryPacketOutput* output); using MaterialPacketEvaluator = void (*)(const MaterialPacketInput&, PairPacket*); /// @brief Evaluates each lane's original checked material graph in order 0..3. /// @note Invalid arithmetic remains a raw invalid pair for the caller's gates. void EvaluateMaterialPacketScalar(const MaterialPacketInput& input, PairPacket* output); /// @brief Evaluates independent material lanes with the checked vector graph. /// @pre The selector has admitted the CPU/OS ISA and current masked FP state. /// @note No lane reduction or model failure is introduced; special packets bridge /// to original scalar arithmetic, preserving components and operation order. void EvaluateMaterialPacketAvx2(const MaterialPacketInput& input, PairPacket* output); /// @brief Baseline-ISA checked addition bridge in lane order 0..3. /// @note Uses the shared checked high/low arithmetic owner; /// invalid pairs are preserved, with no FP-state mutation or normalization here. void ScalarPacketAdd(const PairPacket& left, const PairPacket& right, PairPacket* output); /// @brief Baseline-ISA shared checked multiplication bridge in lane order 0..3. /// @note Raw invalid outputs remain invalid; no component is rounded away. void ScalarPacketMultiply(const PairPacket& left, const PairPacket& right, PairPacket* output); /// @brief Baseline-ISA original checked TwoProduct bridge in lane order 0..3. /// @note Keeps finite/zero/underflow/FMA checks and the caller's FP state. void ScalarPacketTwoProduct(const double left[4], const double right[4], PairPacket* output); /// @brief Selects a private backend from CPU/OS and this thread's FP state. /// @note Never mutates FP state or caches a thread's environment decision. MaterialPacketEvaluator SelectMaterialPacketEvaluator(); /// @brief Pure instruction/OS-state predicate; does not execute ISA probes. bool SupportsMaterialPacketInstructions(std::uint32_t leaf1_ecx, std::uint64_t xcr0, std::uint32_t leaf7_ebx); } // namespace fesa::hex8_internal #endif // FESA_SRC_FESA_ELEMENTS_HEX8_PAIR_SIMD_H_