#pragma once #include #include #include namespace torch::jit { // instruction look like: // op_code X, N // meaning of X, N depend on the op: // O - index into operator table // R - index into register table // I - literal integer // C - index into constant table // P - jump offset relative to beginning of current instruction // F - index into function table // T - index into the type table, used for guard instructions // S - index into object slots // C - index into code table #define FORALL_OPCODES(_) \ _(OP, "O") /* invoke operator X */ \ _(OPN, "OI") /* invoke vararg operator X with N arguments */ \ _(LOAD, "R") /* push a value from a register X */ \ _(MOVE, "R") /* push a value from register X, clearing the register */ \ _(STOREN, "RI") /* store N values to registers [X, X+N) */ \ _(STORE, "R") /* store 1 value to registers X */ \ _(DROP, "") /* drop 1 value from the top of the stack */ \ _(DROPR, "R") /* clear register X */ \ _(LOADC, "C") /* push the constant X */ \ _(JF, "P") /* pop the top of the stack, if false, branch to P */ \ _(JMP, "P") /* unconditional branch to X */ \ _(LOOP, "PI") /* perform a loop, X is where to branch if cond is false */ \ _(RET, "") /* exit execution */ \ _(WAIT, "") /* wait for a future to be complete */ \ _(CALL, "F") /* call function X */ \ _(GUARD, "T") /* check a guard against type_table, true if passes */ \ _(TYPECHECK, "TN") /* check each type of input[i] against type_table[X+N] */ \ _(FAIL_GUARD, "T") /* fail a guard, patch back to GUARD */ \ _(PROFILE_OP, "F") /* get a callback from profile_function_table at X */ \ _(TAIL_CALL, "F") /* replace current frame with function F */ \ _(INTERFACE_CALL, "CI") /* call method X on the first argument (of N) */ \ _(GET_ATTR, "S") /* get attribute from slot X in an Object */ \ _(SET_ATTR, "S") /* set attribute to slot X in an Object */ \ _(LIST_UNPACK, "I") /* unpack list expecting length I */ \ _(TUPLE_CONSTRUCT, "I") /* construct a tuple using X inputs */ \ _(NAMED_TUPLE_CONSTRUCT, \ "TI") /* construct a tuple of type X, using N inputs */ \ _(LIST_CONSTRUCT, "TI") /* construct a list of type X, using N inputs */ \ _(DICT_CONSTRUCT, "TI") /* construct a dict of type X, using N inputs */ \ _(CREATE_OBJECT, "T") /* create an object of type X */ \ _(ISINSTANCE, "TI") /* check object is one of types[X:X+N] */ \ _(TUPLE_SLICE, "II") /* slice tup[X:(X+N)] */ \ _(TUPLE_INDEX, "") /* get the value from a tuple at that index */ \ _(RAISE_EXCEPTION, "") /* throws the exception from Python */ \ _(DICT_INDEX, "") /* gets the value from the dict for given key */ \ _(UNCHECKED_CAST, "") /* perform an unchecked cast operation */ \ _(__IS__, "") /* performs `is` operator from Python */ \ _(UN_INITIALIZED, \ "") /* sets default values to variables that are uninitialized */ \ _(__ISNOT__, "") /* performs `is not` operator from Python */ \ _(FORMAT, "I") /* performs string format function `f strings` or `{}.format` \ the number of inputs in stored in X */ \ _(DEVICE, "") /* invokes aten::device for a Tensor */ \ _(DTYPE, "") /* invokes aten::dtype for a Tensor */ \ _(DIM, "") /* invokes aten::dim for a Tensor */ \ _(__NOT__, "") /* performs `not` operator from Python */ \ _(TO_LIST, "") /* convert the input to a list */ \ _(NUM_TO_TENSOR, \ "") /* performs the conversion of a number/scalar to Tensor */ \ _(IS_CUDA, "") /* invokes aten::is_cuda for a Tensor */ \ _(FORK, "CN") /* launch a thread to run code entry x with N inputs */ \ _(WARN, "I") /* emit a warning with line information */ \ _(ENTER, "EN") /* enter scope of a contextmanager */ \ _(EXIT, "EX") /* exit the last entered contextmanager */ \ _(AWAITABLE, "CN") /* initialize await for code entry x with N inputs */ enum OpCode : uint8_t { #define DEFINE_OP(op, _) op, FORALL_OPCODES(DEFINE_OP) #undef DEFINE_OP }; struct Instruction { OpCode op; uint8_t unused; uint16_t N; int32_t X; // TODO: check for overflow Instruction(OpCode op, int32_t X, uint16_t N) : op(op), unused(0), N(N), X(X) {} }; std::ostream& operator<<(std::ostream& out, Instruction inst); bool isOpSupportedInMobile(OpCode op); char const* toString(OpCode op); OpCode parseOpCode(const char* str); std::ostream& operator<<(std::ostream& out, Instruction inst); } // namespace torch::jit