Repository: pytorch
Issue: Redo our library structure
Labels: module: build,triaged

Design goals:
* Each individual dynamic library must not be too large, or we will hit linking limits per #27215
* Our plan for addressing the above problem is to split `libtorch.so` into `libtorch_cpu.so` and `libtorch_cuda.so` libraries
* It should be obvious which `*_API` macro one should use to annotate a function as public in any given file
* `libtorch_cpu.so` should be the same regardless of if you do a `USE_CUDA` build or not. (But some code has `USE_CUDA` macros; in that case, we cannot achieve this design goal. Goal is to NOT shave this yak before we make an improvement)
* `libtorch.so` is the single dynamic library all end users have to link against; no understanding of the internal library structure should be necessary
* Try not to merge conflict with lots of people when fixing these problems (no unnecessary moves)

Why the current state of affairs violate these design goals:
* We link everything into a single libtorch library which is too big for #27215
* The distinction between torch (C++ only) and Python libraries is extremely unclear, making it hard to tell what the correct `_API` macro usage is: compare the list of files in https://github.com/pytorch/pytorch/blob/9492994feb06dd815753c1d18da490aef88102f6/tools/build_variables.py for `libtorch_sources` versus `libtorch_python_sources`; also compare `libtorch_cuda_sources` versus `libtorch_sources`
* We currently broadly use `TORCH_API` to mark functions exported from `libtorch.so`, but many of these functions would move to `libtorch_cpu.so`, thus making the API annotation inconsistent

As far as I can see, there are a set of orthogonal issues we need to address:
* We need some sort of file organization that makes it easy to tell which library a file lives in. However, the tension here is that if we move everything around, we will merge conflict with every in progress pull request
* We need a logical `_API` naming scheme, tied to the file organization, resulting in an easy to apply rule for which `_API` macro to apply at a point in time
* We need to split the library into two or more parts, to ensure we don't OOM when linking Window

# Proposed new library organization

We follow the internal, fbcode structure (which has more libraries), but condense libraries into:
* libtorch_cuda (corresponding to torch-cuda)
* libtorch_cpu (corresponding to torch-cpu AND torch-cpp); to do this, we must make torch-cpp have no uses of `USE_CUDA` macro
* _C (corresponding to torch-python)

# Proposed new file organization

The new file organization is basically the same as Caffe2's old naming scheme for cuda kernels, but also extended to apply for python.

Files that constitute torch-python:
* In `torch/csrc`, every file that is named `python_*`
  * Rename any file `foo.cpp` which is obviously Python related to `python_foo.cpp` (example: rename `init.cpp` to `python_init.cpp`)
  * However, do NOT rename files which seem Python agnostic; they are probably classified in the wrong library at the moment and we should move them eventually. Add headers to the top of the file indicating their status. Example: `torch/csrc/jit/passes/onnx/cast_all_constant_to_floating.cpp`
  * Move all Python files in top level directory (e.g., `torch/csrc/Dtype.cpp`) to `torch/csrc/python`. Once we do this, only dl.c, stub.cpp and WindowsTorchApiMacro.h will remain in top level.
 
Files that constitute torch-cuda (anything not already matched by torch-python):
* In `torch/csc`, every file that is named `*cuda*`
* Existing ATen rules

Files that constitute torch-cpu: anything not already matched by any of the filters above.

Alternatives:
* Do nothing (but this means it continues to be hard to tell what files belong where)
* Do something more radical, like have a separate folder for each file (but this will result in a lot of merge conflicts)

# Proposed new API macros

* `TORCH_API` for files in `torch-cpu`
* `TORCH_CUDA_API` for files in `torch-cuda`
* `TORCH_PYTHON_API` for files in `torch-python` (previously this is called `THP_API`; this name is OK too)

Alternatives:
* `TORCH_CPU_API` for files in `torch-cpu` (but then we have to do a bunch of renaming = more merge conflicts)