// rl_encoder_context_broadcast.cu — broadcast per-batch trade_context
// (4 dims) + multires_output (12 dims) into the encoder input tensor
// at positions [40..56] for each of the K sequence rows per batch.
//
// The encoder input tensor is [B, K, ENCODER_INPUT_DIM=56] row-major.
// Dims [0..40] are per-snapshot market features (written by
// snap_feature_assemble_batched). Dims [40..56] are per-batch state
// that is CONSTANT across K ��� this kernel broadcasts them.
//
// One thread per (batch × K) row. No shared memory.
// Per `feedback_no_atomicadd`, `feedback_cpu_is_read_only`.

#include <stdint.h>

#define ENCODER_INPUT_DIM     56
#define SNAP_FEATURE_DIM      40
#define TRADE_CONTEXT_DIM      4
#define MULTIRES_DIM          12

extern "C" __global__ void rl_encoder_context_broadcast(
    float*       __restrict__ encoder_input,    // [B × K × ENCODER_INPUT_DIM]
    const float* __restrict__ trade_context,    // [B × TRADE_CONTEXT_DIM]
    const float* __restrict__ multires_output,  // [B × MULTIRES_DIM]
    int                       b_size,
    int                       seq_len
) {
    const int idx = blockIdx.x * blockDim.x + threadIdx.x;
    const int total = b_size * seq_len;
    if (idx >= total) return;

    const int b = idx / seq_len;

    float* row = encoder_input + idx * ENCODER_INPUT_DIM + SNAP_FEATURE_DIM;
    const float* tc = trade_context + b * TRADE_CONTEXT_DIM;
    const float* mr = multires_output + b * MULTIRES_DIM;

    for (int i = 0; i < TRADE_CONTEXT_DIM; ++i) row[i] = tc[i];
    for (int i = 0; i < MULTIRES_DIM; ++i) row[TRADE_CONTEXT_DIM + i] = mr[i];
}
