@@ -2166,3 +2166,79 @@ def test_accuracy_addcdiv(shape, dtype):
21662166 res_out = torch .addcdiv (res_inp , t1 , t2 , value = v )
21672167
21682168 gems_assert_close (res_out , ref_out , dtype )
2169+
2170+
2171+ @pytest .mark .fmod
2172+ @pytest .mark .parametrize ("shape" , POINTWISE_SHAPES )
2173+ @pytest .mark .parametrize ("dtype" , FLOAT_DTYPES )
2174+ def test_accuracy_fmod (shape , dtype ):
2175+ inp1 = torch .randn (shape , dtype = dtype , device = flag_gems .device )
2176+ inp2 = torch .randn (shape , dtype = dtype , device = flag_gems .device )
2177+ # Avoid division by zero
2178+ inp2 = torch .where (inp2 == 0 , torch .ones_like (inp2 ), inp2 )
2179+ ref_inp1 = to_reference (inp1 , True )
2180+ ref_inp2 = to_reference (inp2 , True )
2181+
2182+ ref_out = torch .fmod (ref_inp1 , ref_inp2 )
2183+ with flag_gems .use_gems ():
2184+ res_out = torch .fmod (inp1 , inp2 )
2185+
2186+ gems_assert_close (res_out , ref_out , dtype )
2187+
2188+
2189+ @pytest .mark .fmod
2190+ @pytest .mark .parametrize ("shape" , POINTWISE_SHAPES )
2191+ @pytest .mark .parametrize ("scalar" , SCALARS )
2192+ @pytest .mark .parametrize ("dtype" , FLOAT_DTYPES )
2193+ def test_accuracy_fmod_tensor_scalar (shape , scalar , dtype ):
2194+ inp1 = torch .randn (shape , dtype = dtype , device = flag_gems .device )
2195+ # Avoid division by zero
2196+ inp2 = scalar if scalar != 0 else 1.0
2197+ ref_inp1 = to_reference (inp1 , True )
2198+
2199+ ref_out = torch .fmod (ref_inp1 , inp2 )
2200+ with flag_gems .use_gems ():
2201+ res_out = torch .fmod (inp1 , inp2 )
2202+
2203+ # Use larger tolerance for fmod with small divisors due to float32 precision limits
2204+ atol = 1e-3 if abs (scalar ) < 0.01 else 1e-4
2205+ gems_assert_close (res_out , ref_out , dtype , atol = atol )
2206+
2207+
2208+ @pytest .mark .inplace
2209+ @pytest .mark .fmod_
2210+ @pytest .mark .parametrize ("shape" , POINTWISE_SHAPES )
2211+ @pytest .mark .parametrize ("dtype" , FLOAT_DTYPES )
2212+ def test_accuracy_fmod_ (shape , dtype ):
2213+ inp1 = torch .randn (shape , dtype = dtype , device = flag_gems .device )
2214+ inp2 = torch .randn (shape , dtype = dtype , device = flag_gems .device )
2215+ # Avoid division by zero
2216+ inp2 = torch .where (inp2 == 0 , torch .ones_like (inp2 ), inp2 )
2217+ ref_inp1 = to_reference (inp1 .clone (), True )
2218+ ref_inp2 = to_reference (inp2 , True )
2219+
2220+ ref_out = ref_inp1 .fmod_ (ref_inp2 )
2221+ with flag_gems .use_gems ():
2222+ res_out = inp1 .fmod_ (inp2 )
2223+
2224+ gems_assert_close (res_out , ref_out , dtype )
2225+
2226+
2227+ @pytest .mark .inplace
2228+ @pytest .mark .fmod_
2229+ @pytest .mark .parametrize ("shape" , POINTWISE_SHAPES )
2230+ @pytest .mark .parametrize ("scalar" , SCALARS )
2231+ @pytest .mark .parametrize ("dtype" , FLOAT_DTYPES )
2232+ def test_accuracy_fmod_tensor_scalar_ (shape , scalar , dtype ):
2233+ inp1 = torch .randn (shape , dtype = dtype , device = flag_gems .device )
2234+ # Avoid division by zero
2235+ inp2 = scalar if scalar != 0 else 1.0
2236+ ref_inp1 = to_reference (inp1 .clone (), True )
2237+
2238+ ref_out = ref_inp1 .fmod_ (inp2 )
2239+ with flag_gems .use_gems ():
2240+ res_out = inp1 .fmod_ (inp2 )
2241+
2242+ # Use larger tolerance for fmod with small divisors due to float32 precision limits
2243+ atol = 1e-3 if abs (scalar ) < 0.01 else 1e-4
2244+ gems_assert_close (res_out , ref_out , dtype , atol = atol )
0 commit comments