## Summary
- infer BatchNorm/GroupNorm/InstanceNorm and Softmax/LogSoftmax
shape/dtype metadata from forward inputs instead of requiring
construction-time `N/C/spatial/dtype` metadata
- lazily specialize and JIT kernels in `forward()` with `_kernel_cache`
as the authoritative specialization cache
- retain `self.kernel` as the last-used kernel handle only, so repeated
calls can overwrite it when dispatching a different specialization while
cache hits avoid rebuild/JIT work
- update tests and benchmarks to use the preferred input-derived API
while keeping explicit constructor metadata as optional compatibility
guards
## Kernel Cache / `self.kernel` Contract
- `__init__` no longer eagerly builds kernels for these ops.
- `forward()` resolves the specialization from runtime tensors, looks
up/builds the cached kernel, and assigns `self.kernel = kernel` for
compatibility/debug visibility.
- `_kernel_cache` owns compiled specializations; `self.kernel` is not
the cache and may change on later calls with different input
shapes/devices/dtypes.
- For an already-JITed specialization, the hot path is metadata
validation + cache key lookup + assignment, without another kernel
build.
## Testing
- `python -m py_compile` on changed op/test/benchmark files
- `python -m ruff check` on changed op/test/benchmark files
- local Docker GPU smoke with
`ghcr.io/tile-ai/tileops-runner:65dbc98-torch2.10` on GPU 4:
- `87 passed, 12 skipped, 138 deselected, 14 warnings`
- local Docker manifest checks for affected ops:
- `SoftmaxFwdOp`, `LogSoftmaxFwdOp`, `BatchNormFwdOp`, `BatchNormBwdOp`,
`GroupNormFwdOp`, `GroupNormFwdOpNoAffine`, `InstanceNormFwdOp`,
`InstanceNormFwdOpNoAffine`
- all passed; remaining output is existing advisory
`_infer_output_shapes` warnings
Closes#1686
Refs #1674