@@ -524,8 +524,11 @@ typedef struct OrtKernelImpl OrtKernelImpl;
524524 */
525525struct OrtKernelImpl {
526526 uint32_t ort_version_supported ; ///< Must be initialized to ORT_API_VERSION
527+ uint32_t flags ; ///< EP must initialize to 0. Used internally by ORT.
527528
528529 /** \brief Computation function called to execute the kernel on an EP.
530+ *
531+ * \note Implementation of this function is required.
529532 *
530533 * \param[in] this_ptr The OrtKernelImpl instance.
531534 * \param[in] context The OrtKernelContext instance that provides access to the inputs and outputs.
@@ -537,6 +540,8 @@ struct OrtKernelImpl {
537540 ORT_API2_STATUS (Compute , _In_ OrtKernelImpl * this_ptr , _In_ OrtKernelContext * context );
538541
539542 /** \brief Called by ORT to release the OrtKernelImpl instance and its resources.
543+ *
544+ * \note Implementation of this function is required.
540545 *
541546 * \param[in] this_ptr The OrtKernelImpl instance.
542547 *
@@ -645,7 +650,9 @@ struct OrtKernelImpl {
645650 * \param[in] kernel_create_func_state Opaque state initially provided by the EP that registered the kernel.
646651 * Refer to OrtEpApi::KernelRegistry_AddKernel(). May be null.
647652 * \param[in] info The OrtKernelInfo instance that provides access to the kernel's input and output characteristics.
648- * \param[out] kernel_out Output parameter set to the new OrtKernelImpl instance.
653+ * \param[out] kernel_out Output parameter set to the new OrtKernelImpl instance. On success, ownership of this
654+ * OrtKernelImpl instance transfers to ORT, which will call OrtKernelImpl::Release() to
655+ * release the instance when it is no longer used.
649656 *
650657 * \snippet{doc} snippets.dox OrtStatus Return Value
651658 *
@@ -655,6 +662,89 @@ typedef OrtStatus*(ORT_API_CALL* OrtKernelCreateFunc)(_In_ void* kernel_create_f
655662 _In_ const OrtKernelInfo * info ,
656663 _Outptr_result_maybenull_ OrtKernelImpl * * kernel_out );
657664
665+ struct OrtLoopKernelHelper ;
666+ typedef struct OrtLoopKernelHelper OrtLoopKernelHelper ;
667+
668+ /**
669+ * \brief Contains helper functions for a Loop OrtKernelImpl created via ::CreateLoopKernel().
670+ * \since Version 1.24.
671+ */
672+ struct OrtLoopKernelHelper {
673+ uint32_t ort_version_supported ; ///< Must be initialized to ORT_API_VERSION
674+
675+ /** \brief Called by ORT to release the OrtLoopKernelHelper instance and its resources.
676+ *
677+ * \param[in] this_ptr The OrtLoopKernelHelper instance.
678+ *
679+ * \since Version 1.24.
680+ */
681+ ORT_API_T (void , Release , _In_ OrtLoopKernelHelper * this_ptr );
682+
683+ /** \brief Helper function that concatenates OrtValue instances from each loop iteration into a single
684+ * pre-allocated output buffer.
685+ *
686+ * \note Implementing this function is required for all Loop opset versions.
687+ *
688+ * \param[in] this_ptr The OrtLoopKernelHelper instance.
689+ * \param[in] stream_handle Optional native stream handle that enables asynchronous operations. May be NULL.
690+ * \param[in] per_iteration_outputs Array of OrtValue instances from each iteration. All OrtValue elements have the
691+ * same shape.
692+ * \param[in] num_per_iteration_outputs The number of OrtValue* elements in the `per_iteration_outputs` array.
693+ * \param[out] output The pre-allocated output buffer. Memory is allocated on the device for the EP running the
694+ * Loop node.
695+ * \param[in] output_size_in_bytes The size in bytes of the `output` buffer. It is guaranteed to be large enough
696+ * to hold the concatenated data of each element in `per_iteration_outputs`.
697+ *
698+ * \snippet{doc} snippets.dox OrtStatus Return Value
699+ *
700+ * \since Version 1.24.
701+ */
702+ ORT_API2_STATUS (ConcatOutput , _In_ OrtLoopKernelHelper * this_ptr , _In_opt_ void * stream_handle ,
703+ _In_reads_ (num_per_iteration_outputs ) const OrtValue * const * per_iteration_outputs ,
704+ _In_ size_t num_per_iteration_outputs , _Out_writes_bytes_all_ (output_size_in_bytes ) void * output ,
705+ _In_ size_t output_size_in_bytes );
706+ };
707+
708+ struct OrtScanKernelHelper ;
709+ typedef struct OrtScanKernelHelper OrtScanKernelHelper ;
710+
711+ /**
712+ * \brief Contains helper functions for a Scan OrtKernelImpl created via ::CreateScanKernel().
713+ * \since Version 1.24.
714+ */
715+ struct OrtScanKernelHelper {
716+ uint32_t ort_version_supported ; ///< Must be initialized to ORT_API_VERSION
717+
718+ /** \brief Called by ORT to release the OrtScanKernelHelper instance and its resources.
719+ *
720+ * \param[in] this_ptr The OrtScanKernelHelper instance.
721+ *
722+ * \since Version 1.24.
723+ */
724+ ORT_API_T (void , Release , _In_ OrtScanKernelHelper * this_ptr );
725+
726+ /** \brief Helper function that transposes an OrtValue instance during execution of a Scan kernel.
727+ *
728+ * \note Called for Scan (opset >= 9) when the 'scan_input_axes' or 'scan_output_axes' attributes contain
729+ * non-zero values. Implementing this function is required for Scan opset versions >= 9.
730+ *
731+ * \param[in] this_ptr The OrtScanKernelHelper instance.
732+ * \param[in] permutation An array of integers that defines how the input tensor's axes should be permuted.
733+ * \param[in] num_permutation_elems The number of integer elements in the `permutation` array.
734+ * \param[in] input The input OrtValue tensor to transpose.
735+ * \param[in] stream An optional OrtSyncStream instance to be used for asynchronous operations. May be NULL.
736+ * \param[out] output The pre-allocated output OrtValue instance into which to store the results of the
737+ * transpose operation. Must not be released as it is owned by ORT.
738+ *
739+ * \snippet{doc} snippets.dox OrtStatus Return Value
740+ *
741+ * \since Version 1.24.
742+ */
743+ ORT_API2_STATUS (Transpose , _In_ OrtScanKernelHelper * this_ptr ,
744+ _In_reads_ (num_permutation_elems ) const size_t * permutation , _In_ size_t num_permutation_elems ,
745+ _In_ const OrtValue * input , _In_opt_ OrtSyncStream * stream , _Inout_ OrtValue * output );
746+ };
747+
658748/**
659749 * \brief The OrtEpApi struct provides functions that are relevant to the implementation of an execution provider.
660750 *
@@ -1217,6 +1307,107 @@ struct OrtEpApi {
12171307 * \since Version 1.24
12181308 */
12191309 ORT_API2_STATUS (KernelInfo_GetEp , _In_ const OrtKernelInfo * info , _Outptr_ const OrtEp * * ep );
1310+
1311+ /** \brief Creates an OrtKernelImpl instance for an If operator.
1312+ *
1313+ * Control flow operators require access to ORT session internals to orchestrate subgraph operations.
1314+ * This function allows an EP to create a properly configured OrtKernelImpl with access to ORT internals that
1315+ * the EP can add to its kernel registry.
1316+ *
1317+ * An EP is required to create an OrtKernelDef that keeps input[0] ('cond') on the CPU (i.e., OrtMemTypeCPUInput)
1318+ * as this input is used by CPU logic. The output should remain on the device (i.e., OrtMemTypeDefault), which is
1319+ * the default setting, to avoid copying to/from CPU.
1320+ *
1321+ * Example kernel definition (CXX API):
1322+ * Ort::KernelDef kernel_def = Ort::KernelDefBuilder()
1323+ * .SetDomain("").SetOperatorType("If").SetSinceVersion(21, 22)
1324+ * .SetExecutionProvider("MyEp")
1325+ * .SetInputMemType(0, OrtMemTypeCPUInput) // 'cond' on CPU
1326+ * .SetOutputMemType(0, OrtMemTypeDefault) // output on EP device
1327+ * .AddTypeConstraint("B", ...)
1328+ * .AddTypeConstraint("V", ...).Build();
1329+ *
1330+ * \param[in] kernel_info The ::OrtKernelInfo instance for an If node. This function returns error ORT_FAIL
1331+ * if the opset version specified by `kernel_info` is unsupported.
1332+ * \param[out] kernel_out Output parameter set to the OrtKernelImpl instance for the If node.
1333+ * Must be released via ::ReleaseKernelImpl, unless ownership is transferred
1334+ * to ORT (see OrtKernelCreateFunc and ::KernelRegistry_AddKernel()).
1335+ *
1336+ * \snippet{doc} snippets.dox OrtStatus Return Value
1337+ * \since Version 1.24
1338+ */
1339+ ORT_API2_STATUS (CreateIfKernel , _In_ const OrtKernelInfo * kernel_info , _Outptr_ OrtKernelImpl * * kernel_out );
1340+
1341+ /** \brief Creates an OrtKernelImpl instance for a Loop operator.
1342+ *
1343+ * Control flow operators require access to ORT session internals to orchestrate subgraph operations.
1344+ * This function allows an EP to create a properly configured OrtKernelImpl with access to ORT internals that
1345+ * the EP can add to its kernel registry.
1346+ *
1347+ * An EP is required to create an OrtKernelDef that keeps input[0] ('M') and input[1] ('cond') on the CPU
1348+ * (i.e., OrtMemTypeCPUInput) as these inputs are used by CPU logic. Input[2] ('v_initial') and the output should
1349+ * remain on the device (i.e., OrtMemTypeDefault), which is the default setting, to avoid copying to/from CPU.
1350+ *
1351+ * Example kernel definition (CXX API):
1352+ * Ort::KernelDef kernel_def = Ort::KernelDefBuilder()
1353+ * .SetDomain("").SetOperatorType("Loop").SetSinceVersion(21, 22)
1354+ * .SetExecutionProvider("MyEp")
1355+ * .SetInputMemType(0, OrtMemTypeCPUInput) // 'M' on CPU
1356+ * .SetInputMemType(1, OrtMemTypeCPUInput) // 'cond' on CPU
1357+ * .SetInputMemType(2, OrtMemTypeDefault) // 'v_initial' on EP device
1358+ * .SetOutputMemType(0, OrtMemTypeDefault) // output on EP device
1359+ * .AddTypeConstraint("I", ...)
1360+ * .AddTypeConstraint("B", ...)
1361+ * .AddTypeConstraint("V", ...).Build();
1362+ *
1363+ * \param[in] kernel_info The ::OrtKernelInfo instance for a Loop node. This function returns error ORT_FAIL
1364+ * if the opset version specified by `kernel_info` is unsupported.
1365+ * \param[in] helper A OrtLoopKernelHelper instance that contains helper functions that ORT calls during kernel
1366+ * execution to operate on tensors allocated with the EP's device memory.
1367+ * ORT will call OrtLoopKernelHelper::Release() to release the helper and its resources.
1368+ * \param[out] kernel_out Output parameter set to the OrtKernelImpl instance for the Loop node.
1369+ * Must be released via ::ReleaseKernelImpl, unless ownership is transferred
1370+ * to ORT (see OrtKernelCreateFunc and ::KernelRegistry_AddKernel()).
1371+ *
1372+ * \snippet{doc} snippets.dox OrtStatus Return Value
1373+ * \since Version 1.24
1374+ */
1375+ ORT_API2_STATUS (CreateLoopKernel , _In_ const OrtKernelInfo * kernel_info , _In_ OrtLoopKernelHelper * helper ,
1376+ _Outptr_ OrtKernelImpl * * kernel_out );
1377+
1378+ /** \brief Creates an OrtKernelImpl instance for a Scan operator. Does not support opset versions older than 9.
1379+ *
1380+ * Control flow operators require access to ORT session internals to orchestrate subgraph operations.
1381+ * This function allows an EP to create a properly configured OrtKernelImpl with access to ORT internals that
1382+ * the EP can add to its kernel registry.
1383+ *
1384+ * It is recommended that an EP create an OrtKernelDef that keeps the inputs and outputs on the EP's
1385+ * device (i.e., OrtMemTypeDefault), which is the default setting, to avoid copying to/from CPU.
1386+ *
1387+ * Example kernel definition (CXX API):
1388+ * Ort::KernelDef kernel_def = Ort::KernelDefBuilder()
1389+ * .SetDomain("").SetOperatorType("Scan").SetSinceVersion(21, 22)
1390+ * .SetExecutionProvider("MyEp")
1391+ * .SetInputMemType(0, OrtMemTypeDefault) // input[0] on EP device
1392+ * .SetOutputMemType(0, OrtMemTypeDefault) // output[0] on EP device
1393+ * .AddTypeConstraint("V", ...).Build();
1394+ *
1395+ * \param[in] kernel_info The ::OrtKernelInfo instance for a Scan node. This function returns error ORT_FAIL
1396+ * if the opset version specified by `kernel_info` is unsupported.
1397+ * \param[in] helper A OrtScanKernelHelper instance that contains helper functions that ORT calls during kernel
1398+ * execution to operate on tensors allocated with the EP's device memory.
1399+ * ORT will call OrtScanKernelHelper::Release() to release the helper and its resources.
1400+ * \param[out] kernel_out Output parameter set to the OrtKernelImpl instance for the Scan node.
1401+ * Must be released via ::ReleaseKernelImpl, unless ownership is transferred
1402+ * to ORT (see OrtKernelCreateFunc and ::KernelRegistry_AddKernel()).
1403+ *
1404+ * \snippet{doc} snippets.dox OrtStatus Return Value
1405+ * \since Version 1.24
1406+ */
1407+ ORT_API2_STATUS (CreateScanKernel , _In_ const OrtKernelInfo * kernel_info , _In_ OrtScanKernelHelper * helper ,
1408+ _Outptr_ OrtKernelImpl * * kernel_out );
1409+
1410+ ORT_CLASS_RELEASE (KernelImpl );
12201411};
12211412
12221413/**
0 commit comments