Parallel Thread Execution (PTX or NVPTX) is a low-level parallel thread execution virtual machine and instruction set architecture used in Nvidia's Compute Unified Device Architecture (CUDA) programming environment. The LLVM-based Nvidia CUDA Compiler (NVCC) translates code written in OpenCL C and CUDA C/C++ into PTX instructions (an IL), and the graphics driver contains a compiler which translates PTX instructions into executable binary code, which can run on the processing cores of Nvidia graphics processing units (GPUs). Inline PTX assembly can be used in CUDA and OpenCL.
LLVM with clang also has the ability to generate PTX given CUDA, OpenCL C/C++, SYCL C++ or OpenACC or OpenMP directives. The GNU Compiler Collection also generates PTX to offload given OpenACC or OpenMP directives.
The collection of PTX instructions supported by a certain GPU is determined by its compute capability.
PTX uses an arbitrarily large processor register set; the output from the compiler is almost pure static single-assignment form, with consecutive lines generally referring to consecutive registers. Programs start with declarations of the form
It is a three-argument assembly language, and almost all instructions explicitly list the data type (in sign and width) on which they operate. Register names are preceded with a % character and constants are literal, e.g.:
There are predicate registers, but compiled code in shader model 1.0 uses these only in conjunction with branch commands; the conditional branch is
The <code>setp.cc.type</code> instruction sets a predicate register to the result of comparing two registers of appropriate type, there is also a <code>set</code> instruction, where sets the 32-bit register <code>%r101</code> to <code>0xffffffff</code> if the 64-bit register <code>%rd12</code> is less than or equal to the 64-bit register <code>%rd28</code>. Otherwise <code>%r101</code> is set to <code>0x00000000</code>.
There are a few predefined identifiers that denote pseudoregisters. Among others, <code>%tid, %ntid, %ctaid</code>, and <code>%nctaid</code> contain, respectively, thread indices, block dimensions, block indices, and grid dimensions.
Load (<code>ld</code>) and store (<code>st</code>) commands refer to one of several distinct state spaces (memory banks), e.g. <code>ld.param</code>. There are eight state spaces:
Shared memory is declared in the PTX file via lines at the start of the form:
Writing kernels in PTX requires explicitly registering PTX modules via the CUDA Driver API, typically more cumbersome than using the CUDA Runtime API and Nvidia's CUDA compiler, nvcc. The GPU Ocelot project provided an API to register PTX modules alongside CUDA Runtime API kernel invocations, though the GPU Ocelot is no longer actively maintained.