20 #define ENZYME_INLINE __attribute__((always_inline)) inline
36 template <
int In,
int Out,
typename Activation>
struct Dense {
44 const Real *b = p + (In * Out);
46 for (
int i = 0; i < Out; ++i) {
48 for (
int j = 0; j < In; ++j) {
49 z += W[i * In + j] * in[j];
52 out[i] = Activation::apply(z);
60 template <
typename... Layers>
class PINN {
63 static constexpr
int TotalParams = (0 + ... + Layers::NumParams);
64 static constexpr
int MaxLayerSize = std::max({Layers::InSize..., Layers::OutSize...});
75 std::random_device rd;
76 std::mt19937 gen(rd());
79 auto init_layer = [&](
auto &&
self,
auto index_const) ->
void {
80 constexpr
size_t I = decltype(index_const)::value;
81 if constexpr (I <
sizeof...(Layers)) {
82 using LayerType = std::tuple_element_t<I, Architecture>;
83 Real limit = std::sqrt(6.0 / (LayerType::InSize + LayerType::OutSize));
84 std::uniform_real_distribution<Real> dist(-limit, limit);
86 for (
int i = 0; i < LayerType::NumParams; ++i)
88 self(
self, std::integral_constant<size_t, I + 1>{});
91 init_layer(init_layer, std::integral_constant<size_t, 0>{});
96 if constexpr (I <
sizeof...(Layers)) {
97 using CurrentLayer = std::tuple_element_t<I, Architecture>;
100 CurrentLayer::forward(p_ptr, input_buf, output_buf);
102 p_ptr += CurrentLayer::NumParams;
104 process_layers<I + 1>(p_ptr, output_buf, input_buf);
119 using FirstLayer = std::tuple_element_t<0, Architecture>;
121 for (
int i = 0; i < FirstLayer::InSize; ++i)
124 process_layers<0>(p_ptr, buf1, buf2);
126 constexpr
bool OddLayers = (
sizeof...(Layers) % 2 != 0);
127 return OddLayers ? buf2[0] : buf1[0];
Compile-time feedforward network with static forward.
Definition: pinn_network.hpp:60
std::tuple< Layers... > Architecture
Definition: pinn_network.hpp:62
std::vector< Real > params
Definition: pinn_network.hpp:66
void init_params()
Initialize parameters with layer-wise uniform bounds.
Definition: pinn_network.hpp:74
static constexpr int TotalParams
Definition: pinn_network.hpp:63
static constexpr int MaxLayerSize
Definition: pinn_network.hpp:64
PINN()
Definition: pinn_network.hpp:68
static ENZYME_INLINE Real forward_static(const Real *x_ptr, const Real *p_ptr)
Stateless forward evaluation for a single input.
Definition: pinn_network.hpp:109
static ENZYME_INLINE void process_layers(const Real *&p_ptr, Real *input_buf, Real *output_buf)
Apply all layers in sequence using alternating buffers.
Definition: pinn_network.hpp:95
double Real
Scalar type for PINN utilities.
Definition: pinn_network.hpp:16
#define ENZYME_INLINE
Force inline expansion in performance-critical paths.
Definition: pinn_network.hpp:20
Compile-time dense layer definition.
Definition: pinn_network.hpp:36
static constexpr int NumParams
Definition: pinn_network.hpp:39
static constexpr int OutSize
Definition: pinn_network.hpp:38
static ENZYME_INLINE void forward(const Real *p, const Real *in, Real *out)
Forward pass for a single input vector.
Definition: pinn_network.hpp:42
static constexpr int InSize
Definition: pinn_network.hpp:37
Linear activation.
Definition: pinn_network.hpp:29
static ENZYME_INLINE Real apply(Real x)
Definition: pinn_network.hpp:30
Tanh activation.
Definition: pinn_network.hpp:24
static ENZYME_INLINE Real apply(Real x)
Definition: pinn_network.hpp:25