<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/138207>138207</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[mlir][arith] Add arith.scaling_extf and arith.scaling_truncf
</td>
</tr>
<tr>
<th>Labels</th>
<td>
mlir,
mlir:arith
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
krzysz00
</td>
</tr>
</table>
<pre>
# Motivation
MLIR currently supports some microfloats like f4E2M1FN or f6E3M2FN.
These floats are often meant to be used as part of *microscaling* (MX) floats among implementors of the [mxfloat spec](https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf{
When used as microscaled floats, these small floats are represented as a *block* of B such values (32 must be a supported value of B) and a *scale*, which is a f8E8M0FNU - that is, a float that's all exponent bits.
These microscaling formats support conversion into and out of the format, applying the scale during the conversion process. MLIR currently has no way to represent this conversion
# The operations
To give the definition, mod all the relevant interfaces, fast math flags, etc.
```
def Arith_ScalingExtFOp : ArithOp<"scaling_extf", SameOperandResultShape<"block" "res">> {
let args = (ins FloatLike:$block, AnyFloat:$scale, ...); // Maybe the scale can have one less dimension?
let results = (outs FloatLike:$res);
let summary = "Extend `block` to a larger floating point type, multiplying by the exponent of `scale`";
let description = [{
In effect, this performs
``mlir
%unscaled = arith.extf %block : type($block) to type($res)
%scale.exp = round_away_mantissa(%scale)
arith.mulf %unscaled, %scale.exp
``
That is, when converting to the target datatype, the floats in the block are multiplied by
2^{exponent of the scale}.
Note that, unlike in the example IR above, the type of the scale and the type of the result are
not required to match. For example, one can have a f16 output and a f32 or f8E8M0FNU scale.
}];
}
def Arith_ScalingTruncFOp : ArithOp<"scaling_truncf", SameOperandResultShape<"block" "res">> {
let args = (ins FloatLike:$block, AnyFloat:$scale, ...); // Maybe the scale can have one less dimension?
let results = (outs FloatLike:$res);
let summary = "Truncate `block` to a smaller floating point type, dividing by the exponent of `scale`";
let description = [{
In effect, this performs
``mlir
%scale.exp = round_away_mantissa(%scale)
%scaled = arith.divf %block, %scale.exp
arith.truncf %scaled : type($block) to type($res)
``
That is, when converting to the target datatype, the floats in the block are divided by
2^{exponent of the scale}.
Note that, unlike in the example IR above, the type of the scale and the type of the input are
not required to match. For example, one can have a f16 input and a f32 or f8E8M0FNU scale.
}];
}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzcV92O4jgTfRpzUwIFhwS44AIakEaa7pFm-tO3dy0nrhBvJ3bWdmiYp1-VHWh6ev93Ryut1FITx646derUSSKcUweNuGLZhmXbkeh9bezq2X49u69JMiqMPK8YT-HeeHUUXhnNkjVL1vcfP3yGsrcWtW_O4PquM9Y7cKZFaFVpTdUY4R006hmhmu34_XT_AMZCle_Se75_mMRAjzU6hGGzsAim8qihRaE9eAMFQu9QgnDQCevBVMD4OmRwpWiUPjC-BsYX9z8wvrwGao0-gGq7BlvU3lhHB32NwLJNewq7wHVYsmzL-KL2vnMsXTO-Z3z_8vIyMR3q0rRd73Fi7IHxvTRlT7Ec43tTduNbCOPK2FZ4N25P4-N0nIwp9LhSWjTjTlZsvonF_r9GfS3nGgDlAJvxO8LoEFwrmuaWFYudRYfax7OCSCgaUz5T9aaCDbi-rOEomh4d0ZFyaHvniT9xaQ_KuCEcILaEljFUgMH4mhC81KqsQVGSarFb3Cf7h__BGHwtPKiAUURkYYnxuQMCi6fOaNQeCuXdm-beMgUDUxdIUBp9ROuU0aC0NwGS6f2lXXF7SNp1zZki0HLAC7K3l4WbMJ01JTo3gW80WgsH2sCLOJOuroSCr5W7OR-Rk-YfawTToQ2yd0NFBg7qiCGnxEppFWaC30FrZOCB7lhs8EgCVtqjrUSJgbdKOA-t8DVUjTiEJfRl4CpPhr9kLbGCtVW-fvoSOdud_P5TByxdx_VPHUvvGOcDpU948hXjnMJ9ES1-IshafkbXN_5LLTqM2we5cGCcWwLEWbpj6Q6iPAEa9CDswQFLtyQhpR3sqdEf1TOG6ZgNMe5grc_hVlwe5HMHk8mE8SVLNxBHCe7FucCblpVCQy2OCEYjNOgcSNWiDsSn-ysMG8BfkZjev4MSSqBU10Oub1thz8Mhvjt51BJYnkTUeUJ9F9AIe0AbJUzy6YwiFZy7UEHbN14NSivOAflV2eQ9eRKLzZNA4Gt2ia60qiM5RATZ5kIswAcNWFVY-jjiykGHlrTt4obY_LZRlq4Zz3o9OAOFEtT1CbWZboVqghoi5sVrX5ZU4evqQFHMwLMQcYKnLgS1ptfySbyI81MrtFfOiXAqG5o5nIu5276pbmFRGbcRb6sIFdD146tjvJDxxRkLnBPMGsFTKzxI4cWF_zD00feUDlexXjLBoTcKJRTnkIKzbMfmm9sOXbXG5tvBhgAejMfBru6g1-GhNITHk6DHBHz4DKIwxysIAvQmXrCmb-9EoRK6kEcb0u5PvbIoqchW-LKewN7YSx4KT9q_DoKAapqT5XW9Hwy5Snl4Ul7dN_I8ONN8Sw-toDz6HRbfecaj7XX5m67hacc_4Rv_MdsIzAmP740jPJR_3TmkOir5b9rGXx_yy8Kt3Uh1fLWbX573uDEK6U2MP2lNV9uA72QcoTV_3DVgsI3v5hpKh2H_u6YxhPk9z3hvGJe3jZFcpXKZLsUIV9P5LJ-meb5cjOpVOcunZTpbZBIXcpYVSS6WZV7MqzQvE54sR2rFE54lWTLl02wxXUyKaS54NpW8lJVIZM5mCbZCNZOmObb0Cj1SzvW4mqYLnsxHjSiwceGzg_Mg4GBEl4t0HbRFi9l2ZFcUZFz0B8dmSaOcd69hvfJN-H4JB7MtyzbxbLaFtZSDSG_flSJjb5ajhke9bVZvvwUOytd9MSlNy_iecg7_xp01P4bB3Ie66KtgKO244j8HAAD__3kzS4s">