--- Final Solver (used for performance test) ---
import numpy as np
from numba import njit
import logging

@njit(fastmath=True)
def _numba_outer(v1, v2):
    n1 = len(v1)
    n2 = len(v2)
    res = np.empty((n1, n2), dtype=v1.dtype)
    for i in range(n1):
        for j in range(n2):
            res[i, j] = v1[i] * v2[j]
    return res

class Solver:
    def __init__(self):
        # We pre-compile for standard numerical types to avoid compilation 
        # time being counted towards the first test case.
        dtypes_to_try = [
            np.float64, np.float32, np.float16,
            np.int64, np.int32, np.int16, np.int8,
            np.uint64, np.uint32, np.uint16, np.uint8,
            np.bool_
        ]
        
        self.dtypes = []
        for dt in dtypes_to_try:
            try:
                v = np.ones(1, dtype=dt)
                _numba_outer(v, v)
                self.dtypes.append(dt)
            except Exception:
                pass

    def solve(self, problem, **kwargs) -> np.ndarray:
        v1, v2 = problem
        
        # Ensure we have numpy arrays
        if not isinstance(v1, np.ndarray):
            v1 = np.asarray(v1)
        if not isinstance(v2, np.ndarray):
            v2 = np.asarray(v2)
            
        n1 = len(v1)
        n2 = len(v2)
        if n1 == 0 or n2 == 0:
            return np.outer(v1, v2)
            
        # Determine the resulting data type
        dt = np.promote_types(v1.dtype, v2.dtype)
        
        # Fallback to np.outer for very large arrays (to avoid L3 cache misses
        # that numba's simple loop doesn't handle as well as np.nditer)
        # or for unsupported types
        if n1 > 1400 or n2 > 1400 or dt not in self.dtypes:
            return np.outer(v1, v2)
            
        # Ensure contiguous arrays of the target data type
        v1_c = np.ascontiguousarray(v1, dtype=dt)
        v2_c = np.ascontiguousarray(v2, dtype=dt)
        
        return _numba_outer(v1_c, v2_c)
--- End Solver ---
Running performance test...
============================= test session starts ==============================
platform linux -- Python 3.12.13, pytest-9.0.2, pluggy-1.6.0
rootdir: /tests
plugins: anyio-4.13.0, jaxtyping-0.3.9
collected 3 items

../tests/test_outputs.py .
--- Performance Summary ---
Validity: True
Total Baseline Time: 6.5561s
Total Solver Time:   7.0731s
Raw Speedup:         0.9269 x
Final Reward (Score): 1.0000
---------------------------
.F

=================================== FAILURES ===================================
_____________________________ test_solver_speedup ______________________________

performance_results = {'raw_speedup': 0.9269027804470952, 'speedup': 1.0, 'validity': True}

    def test_solver_speedup(performance_results):
        """Checks if the solver effectively optimized the code."""
>       assert performance_results["raw_speedup"] > 1.0, \
            f"Solver was not faster than baseline (Speedup: {performance_results['raw_speedup']:.2f}x)"
E       AssertionError: Solver was not faster than baseline (Speedup: 0.93x)
E       assert 0.9269027804470952 > 1.0

/tests/test_outputs.py:205: AssertionError
==================================== PASSES ====================================
=========================== short test summary info ============================
PASSED ../tests/test_outputs.py::test_solver_exists
PASSED ../tests/test_outputs.py::test_solver_validity
FAILED ../tests/test_outputs.py::test_solver_speedup - AssertionError: Solver...
=================== 1 failed, 2 passed in 223.57s (0:03:43) ====================
