ai.onnx.Mod / build /webgpu /manifest.json
Xenova's picture
Xenova HF Staff
sync 2e7068faf55e
9b3a220 verified
Raw
History Blame
8.14 kB
{
"domain": "ai.onnx",
"name": "Mod",
"sinceVersion": 13,
"description": "Performs elementwise binary modulo on tensors `A` and `B` with multidirectional broadcasting. When `fmod` is `0` (default), applies Python-style `%` with the sign of the divisor; when `fmod` is `1`, applies C-style `fmod` with the sign of the dividend.",
"inputs": [
{ "role": "A", "dtype": "T", "description": "Dividend tensor." },
{ "role": "B", "dtype": "T", "description": "Divisor tensor." }
],
"outputs": [
{
"role": "C",
"dtype": "T",
"rank": "max(ranks.A, ranks.B)",
"description": "Remainder tensor; same shape as the broadcast result of A and B.",
"shape": "broadcastShape(shapes.A, shapes.B)"
}
],
"attributes": { "fmod": 0 },
"attributeDescriptions": {
"fmod": "Controls the modulo mode: `0` (default) uses Python-style integer mod (sign of divisor); `1` uses C-style `fmod` (sign of dividend, floating-point types only)."
},
"attributeConstraints": { "fmod": { "values": [0, 1] } },
"typeConstraints": { "T": ["float32", "float16", "int32", "uint32", "int16", "int8", "uint8"] },
"args": {
"a": { "kind": "tensor", "semantic": "A", "role": "input" },
"b": { "kind": "tensor", "semantic": "B", "role": "input" },
"c": { "kind": "tensor", "semantic": "C", "role": "output" }
},
"tunables": { "WORKGROUP_SIZE": 256 },
"derive": { "floatFmodContract": "attrs.fmod != 0 or not (dtypes.T == \"f32\" or dtypes.T == \"f16\")" },
"constants": {
"scalar": "dtypes.T",
"usesF16": "dtypes.T == \"f16\"",
"isU32": "dtypes.T == \"u32\"",
"isI32": "dtypes.T == \"i32\"",
"fmod": "attrs.fmod != 0"
},
"variants": [
{
"id": "last_axis_broadcast_vec4",
"priority": 25,
"when": ["ranks.C >= 1", "sameShape(shapes.A, shapes.C)", "ranks.B == 1", "dim(shapes.B, 0) == dim(shapes.C, ranks.C - 1)", "numel(shapes.C) > 0", "numel(shapes.C) % 4 == 0", "f16Ok(dtypes.T)", "floatFmodContract"],
"constants": { "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" },
"passes": [
{
"id": "main",
"name": "Mod.lastAxisBroadcastVec4",
"source": { "shader": "mod-vec4.wgsl.jinja", "inputs": { "perAxisB": true, "axisDim": "dim(shapes.B, 0)" } },
"bindings": [
{
"name": "a",
"arg": "a",
"semantic": "A",
"buffer": { "type": "read-only-storage" },
"elementType": "$vectorScalar"
},
{
"name": "b",
"arg": "b",
"semantic": "B",
"buffer": { "type": "read-only-storage" },
"elementType": "$scalar"
},
{
"name": "c",
"arg": "c",
"semantic": "C",
"buffer": { "type": "storage" },
"elementType": "$vectorScalar"
},
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": {
"name": "Params",
"fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.C) / 4" }]
}
}
],
"dispatch": { "threads": "numel(shapes.C) / 4", "workgroupSize": "tunables.WORKGROUP_SIZE" }
}
]
},
{
"id": "scalar_b_vec4",
"priority": 30,
"when": ["sameShape(shapes.A, shapes.C)", "numel(shapes.B) == 1", "numel(shapes.C) > 0", "numel(shapes.C) % 4 == 0", "f16Ok(dtypes.T)", "floatFmodContract"],
"constants": { "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" },
"passes": [
{
"id": "main",
"name": "Mod.scalarBVec4",
"source": { "shader": "mod-vec4.wgsl.jinja", "inputs": { "scalarB": true } },
"bindings": [
{
"name": "a",
"arg": "a",
"semantic": "A",
"buffer": { "type": "read-only-storage" },
"elementType": "$vectorScalar"
},
{
"name": "b",
"arg": "b",
"semantic": "B",
"buffer": { "type": "read-only-storage" },
"elementType": "$scalar",
"length": 1
},
{
"name": "c",
"arg": "c",
"semantic": "C",
"buffer": { "type": "storage" },
"elementType": "$vectorScalar"
},
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": {
"name": "Params",
"fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.C) / 4" }]
}
}
],
"dispatch": { "threads": "numel(shapes.C) / 4", "workgroupSize": "tunables.WORKGROUP_SIZE" }
}
]
},
{
"id": "same_shape_vec4",
"priority": 26,
"when": ["sameShape(shapes.A, shapes.C)", "sameShape(shapes.B, shapes.C)", "numel(shapes.C) > 0", "numel(shapes.C) % 4 == 0", "f16Ok(dtypes.T)", "floatFmodContract"],
"constants": { "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" },
"passes": [
{
"id": "main",
"name": "Mod.vec4",
"source": { "shader": "mod-vec4.wgsl.jinja", "inputs": {} },
"bindings": [
{
"name": "a",
"arg": "a",
"semantic": "A",
"buffer": { "type": "read-only-storage" },
"elementType": "$vectorScalar"
},
{
"name": "b",
"arg": "b",
"semantic": "B",
"buffer": { "type": "read-only-storage" },
"elementType": "$vectorScalar"
},
{
"name": "c",
"arg": "c",
"semantic": "C",
"buffer": { "type": "storage" },
"elementType": "$vectorScalar"
},
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": {
"name": "Params",
"fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.C) / 4" }]
}
}
],
"dispatch": { "threads": "numel(shapes.C) / 4", "workgroupSize": "tunables.WORKGROUP_SIZE" }
}
]
},
{
"id": "broadcast",
"when": ["ranks.A >= 0", "ranks.B >= 0", "ranks.C >= 0", "ranks.A <= ranks.C", "ranks.B <= ranks.C", "f16Ok(dtypes.T)", "floatFmodContract"],
"passes": [
{
"id": "main",
"name": "Mod",
"source": {
"shader": "mod.wgsl.jinja",
"inputs": {
"aShape": "shapes.A",
"bShape": "shapes.B",
"cShape": "shapes.C",
"aRank": "ranks.A",
"bRank": "ranks.B",
"cRank": "ranks.C"
}
},
"bindings": [
{
"name": "a",
"arg": "a",
"semantic": "A",
"buffer": { "type": "read-only-storage" },
"elementType": "$scalar"
},
{
"name": "b",
"arg": "b",
"semantic": "B",
"buffer": { "type": "read-only-storage" },
"elementType": "$scalar"
},
{ "name": "c", "arg": "c", "semantic": "C", "buffer": { "type": "storage" }, "elementType": "$scalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.C)" }] }
}
],
"dispatch": { "threads": "numel(shapes.C)", "workgroupSize": "tunables.WORKGROUP_SIZE" }
}
]
}
]
}