pytorch/pytorch
c10
Active contributors: ezyang, malfet
Purpose
c10/ is PyTorch's lowest-level core: header-only and .cpp files defining the fundamental types every other layer uses — Tensor, Storage, TensorImpl, allocators, dispatch keys, devices, scalar types, and a small number of utilities like c10::SmallVector, c10::ArrayRef, and c10::optional (now a re-export of std::optional). The name comes from "Caffe2 Core 10" — c10 was extracted as the merger glue between Caffe2 and ATen, and survived the deprecation of the rest of Caffe2.
c10 exists so that ATen and Caffe2 historically (and now ATen, the dispatcher, and the JIT) could share the same Tensor plumbing. It deliberately has no dependencies on ATen.
Directory layout
| Path | Contents |
|---|---|
c10/core/ |
TensorImpl, Storage, Allocator, Device, ScalarType, DispatchKey, DispatchKeySet, Layout |
c10/util/ |
SmallVector, ArrayRef, intrusive_ptr, Logging, Exception, Half/BFloat16/Float8 types |
c10/macros/ |
Compiler/platform macros, export annotations |
c10/cuda/ |
CUDA-specific shared facilities: CUDACachingAllocator, CUDAStream, CUDAGuard |
c10/hip/ |
ROCm/HIP equivalents (mostly mirrors c10/cuda/) |
c10/xpu/ |
Intel XPU shared facilities |
c10/metal/ |
Apple MPS / Metal shared facilities |
c10/mobile/ |
Mobile-specific bits (PyTorch Mobile uses a stripped c10) |
c10/test/ |
Unit tests for c10 internals |
c10/benchmark/ |
Microbenchmarks for c10 hot paths |
The README at c10/README.md is short — c10 documents itself by header.
Key abstractions
| Type | File | Purpose |
|---|---|---|
c10::TensorImpl |
c10/core/TensorImpl.h |
The actual tensor object: shape, strides, storage_offset, dtype, device, keyset |
c10::Storage / StorageImpl |
c10/core/Storage.h, StorageImpl.h |
Reference-counted device memory wrapper |
c10::Allocator |
c10/core/Allocator.h |
Per-device allocator interface |
c10::Device |
c10/core/Device.h |
(DeviceType, DeviceIndex) pair |
c10::DispatchKey |
c10/core/DispatchKey.h |
Enum of all dispatch keys |
c10::DispatchKeySet |
c10/core/DispatchKeySet.h |
Bitmap of dispatch keys |
c10::ScalarType |
c10/core/ScalarType.h |
dtype enum + traits |
c10::Scalar |
c10/core/Scalar.h |
Type-erased scalar (int / double / complex / bool) |
c10::SymInt, c10::SymBool |
c10/core/SymInt.h, SymBool.h |
Symbolic integer/bool used by dynamic shapes |
c10::intrusive_ptr<T> |
c10/util/intrusive_ptr.h |
Reference counting smart pointer, used for everything |
c10::cuda::CUDACachingAllocator |
c10/cuda/CUDACachingAllocator.h |
The well-known caching allocator that every CUDA tensor allocates from |
How it works
c10 is mostly a headers + traits library; the action happens elsewhere. There are two structural ideas worth understanding.
Intrusive reference counting
Almost every shared type in c10 (TensorImpl, StorageImpl, Generator, FunctionSchema, OperatorEntry, …) is held via c10::intrusive_ptr<T>. The refcount lives inside the object instead of in a control block (as std::shared_ptr would). This saves an allocation and one indirection on every refcount bump — meaningful given that millions of tensors and storages exist at runtime.
intrusive_ptr requires the held type to inherit from c10::intrusive_ptr_target. Tensor (the user-facing C++ type in ATen) is itself just an intrusive_ptr<TensorImpl> with a richer API. See aten/src/ATen/templates/TensorBody.h for the wrapper.
DispatchKeySet on every tensor
Each TensorImpl carries a DispatchKeySet (c10/core/DispatchKeySet.h). At op call time, the dispatcher takes the union of (input tensors' keysets, ambient TLS keysets) and selects the highest-priority key with a registered kernel. The whole compiler stack, autograd, autocast, vmap, and functionalization plug into the system by registering kernels for specific dispatch keys; see Dispatcher.
Caching allocator
c10::cuda::CUDACachingAllocator (c10/cuda/CUDACachingAllocator.cpp is ~5K lines) is the centerpiece of CUDA memory management. It holds onto freed blocks in size-bucketed pools rather than calling cudaFree, which would synchronize the device. This is also where features like expandable_segments, memory snapshots, allocator hooks, and the OOM debugging APIs live. The allocator is configurable via PYTORCH_CUDA_ALLOC_CONF.
Integration points
- Upwards into ATen. Every header under
aten/src/ATen/includes pieces of c10 (Tensor.h,Scalar.h,Device.h, …). - Upwards into the dispatcher.
c10/core/DispatchKey.handDispatchKeySet.hare the foundation ofaten/src/ATen/core/dispatch/Dispatcher.h. - Sideways into backends.
c10/cuda/,c10/hip/,c10/xpu/,c10/metal/are the per-device runtime helpers (streams, events, guards, allocators) shared by both ATen kernels and Python bindings. - Mobile build.
c10/mobile/is selectively included in the mobile build; the rest of c10 is small enough that it survives mobile linking.
Entry points for modification
If you need a new dispatch key, edit c10/core/DispatchKey.h and update the priority ordering in DispatchKeySet.cpp. If you need a new dtype, edit c10/core/ScalarType.h and the helpers in c10/util/Half.h (or add a new Float8_* header alongside the existing ones). For allocator behaviour changes the surface is c10/cuda/CUDACachingAllocator.cpp.
c10 is intentionally conservative — most contributors should not need to touch it. When you do, expect to update many call sites in ATen and the generated code under aten/src/ATen/Operators_*.cpp.
Key source files
| File | Purpose |
|---|---|
c10/core/TensorImpl.h |
The actual tensor object |
c10/core/Storage.h |
Reference-counted memory wrapper |
c10/core/DispatchKey.h |
Enum of dispatch keys |
c10/core/DispatchKeySet.h |
KeySet bitmap |
c10/core/Allocator.h |
Allocator interface |
c10/core/ScalarType.h |
Dtype enum and traits |
c10/core/SymInt.h |
Symbolic integer for dynamic shapes |
c10/util/intrusive_ptr.h |
Refcount smart pointer |
c10/cuda/CUDACachingAllocator.cpp |
CUDA caching allocator |
c10/cuda/CUDAStream.h |
CUDA stream wrapper |
c10/macros/Macros.h |
Cross-platform macros |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.