Skip to content

NOP Sentinel & RESET Forced Termination ​

NOP and RESET are two special atomic instructions in AmritaSense’s instruction set. They are not SelfCompileInstruction and have no compile-time expansion. Instead, they exist as individual nodes in the workflow, and their behavior is defined purely at runtime.

NOP sentinel instruction ​

NOP (No Operation) is an empty sentinel node. Its significance is not in doing work, but in standing in place to provide a valid jump target.

Implementation ​

python
@_node_fun(wrap_to_async=False, address_able=True)
def _no_operation() -> None:
    pass


NOP: _Node[None] = _no_operation

Key attributes ​

  • address_able=True: this is its most important property. An addressable node can be tagged with ALIAS and become a target for JMP or INVOKE. NOP makes this role explicit.
  • wrap_to_async=False: it is a pure synchronous function that returns immediately, with almost zero overhead.

Typical uses ​

As a convergence point for jumps: in conditional branches, different paths can converge on the same NOP.

python
IF(cond, JMP("then")) >> ... >> ALIAS(NOP, "end_if")

NOP provides a common continuation address for different control flow paths.

As a subroutine return point: subroutines archived in ARCHIVED_NODES often end with NOP. After the subroutine finishes, the interpreter steps to NOP, and call_sub then pops the return address.

As an empty ELSE branch: IF(cond, do).ELSE(NOP) expresses “do nothing when the condition is false” explicitly.

RESET forced termination instruction ​

RESET is the workflow’s emergency stop button. When executed, the workflow terminates immediately and unconditionally.

Implementation ​

python
@_node_fun(wrap_to_async=False, address_able=False)
def _reset_operation() -> NoReturn:
    raise InterruptNotice("Reset Node")


RESET: _Node[NoReturn] = _reset_operation

Execution mechanism ​

  1. Raise InterruptNotice: this exception is a subclass of BaseException, not a regular Exception.
  2. Global catch: the interpreter’s main loop catches InterruptNotice at the top level and enters cleanup.
  3. Clean termination: it calls WorkflowInterpreter.reset(), which clears _pointer, _ret_addr_stack, _context_stack, the entire status register and the panic state, then exits.

Key attributes ​

  • address_able=False: it is a terminator, so it should never be a jump target. Jumping to a node that immediately terminates is meaningless.
  • NoReturn return type: the type system makes it clear that code after RESET is unreachable.

Exception penetration rules ​

InterruptNotice inherits from BaseException. In Python, except Exception does not catch BaseException subclasses, so workflow Try/CATCH blocks do not catch InterruptNotice by default. It naturally penetrates upward.

The only exception is when InterruptNotice is explicitly included in the exception_ignored tuple during WorkflowInterpreter initialization, at which point it becomes catchable. However, that is rarely necessary — RESET is designed to be an “uncatchable” emergency stop.

Usage scenarios ​

  • External signal response: when an external system issues a termination signal, the next node boundary can trigger RESET.
  • Emergency safety stop: insert RESET in the workflow when an unrecoverable error or dangerous condition occurs.
  • Timeout handling: a node can check timeout conditions before execution and raise RESET to force termination.

SUSPEND context-preserving termination ​

SUSPEND is a variant termination node that raises InterruptKeepContext instead of InterruptNotice. Unlike RESET, the interpreter does not call reset() after catching this exception — the pointer, call stack, dependency injection parameters, and all execution state are preserved for later recovery.

Implementation ​

python
@_node_fun(wrap_to_async=False, address_able=True)
def _suspend_operation() -> NoReturn:
    raise InterruptKeepContext("Suspend Node with context retention")


SUSPEND: _Node[NoReturn] = _suspend_operation

Key attributes ​

  • address_able=True: unlike RESET, this node can be aliased and placed in ARCHIVED_NODES as a target.
  • NoReturn: same as RESET — the node never returns normally.
  • Raises InterruptKeepContext (a subclass of InterruptNotice).

Execution mechanism ​

  1. Raise InterruptKeepContext: a BaseException subclass that the interpreter's main loop catches.
  2. Interpreter response: the main loop checks isinstance(e, InterruptKeepContext). If true, it skips the reset() call — the pointer, stacks, and dependency args are left intact.
  3. State preserved: _panic_exc is set, _waiter_fut receives the exception.
  4. Recovery: call run() or run_step_by() again on the same interpreter to resume from the preserved state.

Comparison with RESET ​

AspectRESETSUSPEND
ExceptionInterruptNoticeInterruptKeepContext
After catchreset() — clears all stateSkips reset() — state preserved
AddressableNoYes
RecoverableNo (fresh start required)Yes (call run() to resume)
Use caseEmergency terminationPause-inspect-resume, debug breakpoints

Usage scenarios ​

  • Pause-inspect-resume: terminate with context preserved, inspect state via get_exception(), then run() to resume.
  • Debug breakpoints: place SUSPEND in ARCHIVED_NODES, call externally via call_sub(interrupt=True) to break and inspect.
  • Checkpoint-restart: save work-in-progress state, restart from the exact point later.

Comparison summary ​

NOPRESETSUSPEND
Responsibilityplaceholder, convergence, return pointemergency terminationpause with context preservation
Addressableyesnoyes
Return typeNoneNoReturnNoReturn
Control impactnone, execution continuesterminates, clears stateterminates, preserves state
Typical positionALIAS target, branch tail, subroutine enderror branch end, timeout pathdebug breakpoints, ARCHIVED_NODES

NOP is the silent scaffolding for complex control flow, while RESET is the final safety valve. Together, they form the foundation of AmritaSense’s execution control system.

Apache 2.0 License