layout | title | permalink |
---|---|---|
page |
Implementation Status of WebNN Operations |
/webnn-status/ |
LiteRT
DirectML
Core ML
✅ Supported ()
⏳ Partly Implemented ()
🚀 Work in Progress ()
❌ Not Supported
✅ Supported ()
⏳ Partly Implemented ()
🚀 Work in Progress ()
❌ Not Supported
✅ Supported ()
⏳ Partly Implemented ()
🚀 Work in Progress ()
❌ Not Supported
ONNX Runtime Web
Execution Provider
Execution Provider
LiteRT
External Delegate
External Delegate
✅ Supported ()
⏳ Partly Implemented ()
🚀 Work in Progress ()
❌ Not Supported
✅ Supported ()
⏳ Partly Implemented ()
🚀 Work in Progress ()
❌ Not Supported
The total number of WebNN ops is 78. These tables currently lists ops that are implemented or work in progress by multiple backends and JavaScript machine learning frameworks.
[1] LiteRT Builtin Options
[2] DirectML API
[3] Core ML operators
[4] This feature is experimental. Can be enabled by setting #web-machine-learning-neural-network
flag to Enabled
.
[5] This feature is experimental. Can be enabled by setting #web-machine-learning-neural-network
flag to Enabled
. Supported on GPUs on Windows 11 21H2 or higher.
[6] This feature is experimental. Can be enabled by setting #web-machine-learning-neural-network
flag to Enabled
.
[7] ONNX Operator Schemas
and WebNN EP Helper
[8] LiteRT built-in operators kTfLiteBuiltin*
🏅🏅🏅 Interested in contributing to this implementation status page? See contributing guidelines.
<script> const qS = (selector) => { return document.querySelector(selector); } const qSA = (selector) => { return document.querySelectorAll(selector); } const init = () => { let ops = document.querySelector('#ops'); let opsFramework = document.querySelector('#ops_framework'); let jsonPath = "../assets/json/webnn_status.json"; if(location.hostname.toLowerCase().indexOf('webmachinelearning.github.io') >-1) { jsonPath = "https://webmachinelearning.github.io/assets/json/webnn_status.json"; } fetch(jsonPath) .then(response => response.json()) .then(data => { let impl_status = data.impl_status; let oplist = ''; let oplistFramework = ''; for (let s of impl_status) { let spec = `${s.op}` let wpt = ''; if (s.wpt_progress === 4) { wpt = ` 📈 🧪` } if (s.wpt_progress === 3) { wpt = `🚀🚀` } let tflite = ''; if (s.tflite_op.toString().trim() === "") { tflite = `${s.tflite_chromium_version_added}`; } else if (s.tflite_progress === 4) { let tflite_ops = ''; if (s.tflite_op.length > 1) { for (let o of s.tflite_op) { tflite_ops = `✅ ${o}`; tflite += tflite_ops; } } else if (s.tflite_op.length === 1) { tflite = '✅ ' + s.tflite_op; } else { tflite = `` } tflite = `${tflite}${s.tflite_chromium_version_added}`; } else if (s.tflite_progress === 3) { let tflite_ops = ''; if (s.tflite_op.length > 1) { for (let o of s.tflite_op) { tflite_ops = `🚀 ${o}
`; tflite += tflite_ops; } } else if (s.tflite_op.length === 1) { tflite = '🚀 ' + s.tflite_op; } else { tflite = `` } tflite = `${tflite}${s.tflite_chromium_version_added}`; } else if (s.tflite_progress === 2) { let tflite_ops = ''; if (s.tflite_op.length > 1) { for (let o of s.tflite_op) { tflite_ops = `📅 ${o}
`; tflite += tflite_ops; } } else if (s.tflite_op.length === 1) { tflite = '📅 ' + s.tflite_op; } else { tflite = `` } tflite = `${tflite}${s.tflite_chromium_version_added}`; } else { tflite = `${s.tflite_chromium_version_added}`; } let dml = ''; if (s.dml_op.toString().trim() === "") { dml = `${s.dml_chromium_version_added}`; } else if (s.dml_progress === 4) { let dml_ops = ''; if (s.dml_op.length > 1) { for (let o of s.dml_op) { dml_ops = `✅ ${o}
`; dml += dml_ops; } } else if (s.dml_op.length === 1) { dml = '✅ ' + s.dml_op; } else { dml = `` } dml = `${dml}${s.dml_chromium_version_added}`; } else if (s.dml_progress === 3) { let dml_ops = ''; if (s.dml_op.length > 1) { for (let o of s.dml_op) { dml_ops = `🚀 ${o}
`; dml += dml_ops; } } else if (s.dml_op.length === 1) { dml = '🚀 ' + s.dml_op; } else { dml = `` } dml = `${dml}${s.dml_chromium_version_added}`; } else if (s.dml_progress === 2) { let dml_ops = ''; if (s.dml_op.length > 1) { for (let o of s.dml_op) { dml_ops = `📅 ${o}
`; dml += dml_ops; } } else if (s.dml_op.length === 1) { dml = '📅 ' + s.dml_op; } else { dml = `` } dml = `${dml}${s.dml_chromium_version_added}`; } else { dml = `${s.dml_chromium_version_added}`; } let coreml = ''; if (s.coreml_op.toString().trim() === "") { coreml = `${s.coreml_chromium_version_added}`; } else if (s.coreml_progress === 4) { let coreml_ops = ''; if (s.coreml_op.length > 1) { for (let o of s.coreml_op) { coreml_ops = `✅ ${o}
`; coreml += coreml_ops; } } else if (s.coreml_op.length === 1) { coreml = '✅ ' + s.coreml_op; } else { coreml = `` } coreml = `${coreml}${s.coreml_chromium_version_added}`; } else if (s.coreml_progress === 3) { let coreml_ops = ''; if (s.coreml_op.length > 1) { for (let o of s.coreml_op) { coreml_ops = `🚀 ${o}
`; coreml += coreml_ops; } } else if (s.coreml_op.length === 1) { coreml = '🚀 ' + s.coreml_op; } else { coreml = `` } coreml = `${coreml}${s.coreml_chromium_version_added}`; } else if (s.coreml_progress === 2) { let coreml_ops = ''; if (s.coreml_op.length > 1) { for (let o of s.coreml_op) { coreml_ops = `📅 ${o}
`; coreml += coreml_ops; } } else if (s.coreml_op.length === 1) { coreml = '📅 ' + s.coreml_op; } else { coreml = `` } coreml = `${coreml}${s.coreml_chromium_version_added}`; } else { coreml = `${s.coreml_chromium_version_added}`; } let fw_tflite = ''; if (s.fw_tflite_op.toString().trim() === "") { fw_tflite = `${s.fw_tflite_version_added}`; } else if (s.fw_tflite_progress === 4) { let fw_tflite_ops = ''; if (s.fw_tflite_op.length > 1) { for (let o of s.fw_tflite_op) { fw_tflite_ops = `✅ ${o}
`; fw_tflite += fw_tflite_ops; } } else if (s.fw_tflite_op.length === 1) { fw_tflite = '✅ ' + s.fw_tflite_op; } else { fw_tflite = `` } fw_tflite = `${fw_tflite}${s.fw_tflite_version_added}`; } else if (s.fw_tflite_progress === 3) { let fw_tflite_ops = ''; if (s.fw_tflite_op.length > 1) { for (let o of s.fw_tflite_op) { fw_tflite_ops = `🚀 ${o}
`; fw_tflite += fw_tflite_ops; } } else if (s.fw_tflite_op.length === 1) { fw_tflite = '🚀 ' + s.fw_tflite_op; } else { fw_tflite = `` } fw_tflite = `${fw_tflite}${s.fw_tflite_version_added}`; } else if (s.fw_tflite_progress === 2) { let fw_tflite_ops = ''; if (s.fw_tflite_op.length > 1) { for (let o of s.fw_tflite_op) { fw_tflite_ops = `📅 ${o}
`; fw_tflite += fw_tflite_ops; } } else if (s.fw_tflite_op.length === 1) { fw_tflite = '📅 ' + s.fw_tflite_op; } else { fw_tflite = `` } fw_tflite = `${fw_tflite}${s.fw_tflite_version_added}`; } else { fw_tflite = `${s.fw_tflite_version_added}`; } let fw_ort = ''; if (s.fw_ort_op.toString().trim() === "") { fw_ort = `${s.fw_ort_version_added}`; } else if (s.fw_ort_progress === 4) { let fw_ort_ops = ''; if (s.fw_ort_op.length > 1) { for (let o of s.fw_ort_op) { fw_ort_ops = `✅ ${o}
`; fw_ort += fw_ort_ops; } } else if (s.fw_ort_op.length === 1) { fw_ort = '✅ ' + s.fw_ort_op; } else { fw_ort = `` } fw_ort = `${fw_ort}${s.fw_ort_version_added}`; } else if (s.fw_ort_progress === 3) { let fw_ort_ops = ''; if (s.fw_ort_op.length > 1) { for (let o of s.fw_ort_op) { fw_ort_ops = `🚀 ${o}
`; fw_ort += fw_ort_ops; } } else if (s.fw_ort_op.length === 1) { fw_ort = '🚀 ' + s.fw_ort_op; } else { fw_ort = `` } fw_ort = `${fw_ort}${s.fw_ort_version_added}`; } else if (s.fw_ort_progress === 2) { let fw_ort_ops = ''; if (s.fw_ort_op.length > 1) { for (let o of s.fw_ort_op) { fw_ort_ops = `📅 ${o}
`; fw_ort += fw_ort_ops; } } else if (s.fw_ort_op.length === 1) { fw_ort = '📅 ' + s.fw_ort_op; } else { fw_ort = `` } fw_ort = `${fw_ort}${s.fw_ort_version_added}`; } else { fw_ort = `${s.fw_ort_version_added}`; } oplist += ` ${spec} ${wpt} ${tflite} ${dml} ${coreml} `; oplistFramework += ` ${spec} ${fw_ort} ${fw_tflite} `; } oplist = oplist + ` `; oplistFramework = oplistFramework + ` `; ops.innerHTML = oplist; opsFramework.innerHTML = oplistFramework; count(); }) .catch(console.error); } const count = () => { let spec_defined_total = 91; let spec_s = qSA('.spec').length / 2; qS('#spec_total').innerHTML = `${spec_s}`; qS('#spec2_total').innerHTML = `${spec_s}`; let wpt_s = qSA('.wpt_s').length; let wpt_percentage = (wpt_s / spec_defined_total * 100).toFixed(1) ; qS('#wpt_total').innerHTML = `${wpt_s} / ${spec_defined_total}, ${wpt_percentage}%`; let tflite_s = qSA('.tflite_s').length; let tflite_pi = qSA('.tflite_pi').length; let tflite_wip = qSA('.tflite_wip').length; let tflite_percentage = (tflite_s / spec_defined_total * 100).toFixed(1) ; qS('#tflite_total').innerHTML = `${tflite_s} / ${spec_defined_total}, ${tflite_percentage}%`; qS('#tflite_supported').innerHTML = tflite_s; qS('#tflite_partlyimplemented').innerHTML = tflite_pi; qS('#tflite_workinprogress').innerHTML = tflite_wip; let dml_s = qSA('.dml_s').length; let dml_pi = qSA('.dml_pi').length; let dml_wip = qSA('.dml_wip').length; let dml_percentage = (dml_s / spec_defined_total * 100).toFixed(1) ; qS('#dml_total').innerHTML = `${dml_s} / ${spec_defined_total}, ${dml_percentage}%`; qS('#dml_supported').innerHTML = dml_s; qS('#dml_partlyimplemented').innerHTML = dml_pi; qS('#dml_workinprogress').innerHTML = dml_wip; let coreml_s = qSA('.coreml_s').length; let coreml_pi = qSA('.coreml_pi').length; let coreml_wip = qSA('.coreml_wip').length; let coreml_percentage = (coreml_s / spec_defined_total * 100).toFixed(1) ; qS('#coreml_total').innerHTML = `${coreml_s} / ${spec_defined_total}, ${coreml_percentage}%`; qS('#coreml_supported').innerHTML = coreml_s; qS('#coreml_partlyimplemented').innerHTML = coreml_pi; qS('#coreml_workinprogress').innerHTML = coreml_wip; let ed_s = qSA('.ed_s').length; let ed_pi = qSA('.ed_pi').length; let ed_wip = qSA('.ed_wip').length; let ed_percentage = (ed_s / spec_defined_total * 100).toFixed(1) ; qS('#ed_total').innerHTML = `${ed_s} / ${spec_defined_total}, ${ed_percentage}%`; qS('#ed_supported').innerHTML = ed_s; qS('#ed_partlyimplemented').innerHTML = ed_pi; qS('#ed_workinprogress').innerHTML = ed_wip; let ep_s = qSA('.ep_s').length; let ep_pi = qSA('.ep_pi').length; let ep_wip = qSA('.ep_wip').length; let ep_percentage = (ep_s / spec_defined_total * 100).toFixed(1) ; qS('#ep_total').innerHTML = `${ep_s} / ${spec_defined_total}, ${ep_percentage}%`; qS('#ep_supported').innerHTML = ep_s; qS('#ep_partlyimplemented').innerHTML = ep_pi; qS('#ep_workinprogress').innerHTML = ep_wip; } document.addEventListener('DOMContentLoaded', init, false); </script>