Generate header with version #defines for LibTorch (#50073)

Summary:
Uses cmake's `configure_file()` macro to generate a new `torch/csrc/api/include/torch/version.h` header with `TORCH_VERSION_{MAJOR,MINOR,PATCH}` \#defines from an input file `torch/csrc/api/include/torch/version.h.in`.

For Bazel builds, this is accomplished with `header_template_rule()`.

For Buck builds, this is accomplished with `fb_native.genrule()`.

Fixes https://github.com/pytorch/pytorch/issues/44365

<img width="1229" alt="Screen Shot 2021-01-05 at 3 19 24 PM" src="https://user-images.githubusercontent.com/75754324/103809279-3fd80380-5027-11eb-9039-fd23922cebd5.png">

Pull Request resolved: https://github.com/pytorch/pytorch/pull/50073

Reviewed By: glaringlee

Differential Revision: D25855877

Pulled By: jbschlosser

fbshipit-source-id: 6bb792718c97e2c2dbaa74b7b7b831a4f6938e49
This commit is contained in:
Joel Schlosser
2021-02-03 22:16:04 -08:00
committed by Facebook GitHub Bot
parent 23c50a4a50
commit e60f18c2ad
7 changed files with 141 additions and 1 deletions

1
.gitignore vendored
View File

@ -65,6 +65,7 @@ torch/csrc/autograd/generated/*
# Listed manually because some files in this directory are not generated
torch/testing/_internal/generated/annotated_fn_args.py
torch/testing/_internal/data/*.pt
torch/csrc/api/include/torch/version.h
torch/csrc/cudnn/cuDNN.cpp
torch/csrc/deploy/interpreter/cpython
torch/csrc/deploy/interpreter/frozen

View File

@ -1868,6 +1868,19 @@ cc_library(
)
# torch
py_binary(
name = "gen_version_header",
srcs = ["tools/setup_helpers/gen_version_header.py"],
)
genrule(
name = "version_h",
srcs = ["torch/csrc/api/include/torch/version.h.in", "version.txt"],
outs = ["torch/csrc/api/include/torch/version.h"],
cmd = "$(location :gen_version_header) --template-path $(location torch/csrc/api/include/torch/version.h.in) --version-path $(location version.txt) --output-path $@",
tools = [':gen_version_header']
)
torch_cuda_headers = glob(["torch/csrc/cuda/*.h"])
cc_library(
name = "torch_headers",
@ -1888,7 +1901,7 @@ cc_library(
"torch/csrc/autograd/generated/variable_factories.h",
"torch/csrc/autograd/generated/Functions.h",
] + torch_cuda_headers,
) + [":cpp_generated_code"],
) + [":cpp_generated_code", ":version_h"],
includes = [
"torch/csrc",
"torch/csrc/api/include",

View File

@ -388,6 +388,10 @@ if(NOT INTERN_BUILD_MOBILE OR NOT BUILD_CAFFE2_MOBILE)
"${TOOLS_PATH}/shared/_utils_internal.py"
COPYONLY)
# Generate header with version info
configure_file("${TORCH_SRC_DIR}/csrc/api/include/torch/version.h.in"
"${TORCH_SRC_DIR}/csrc/api/include/torch/version.h"
@ONLY)
set(GENERATED_CXX_TORCH
"${TORCH_SRC_DIR}/csrc/autograd/generated/Functions.cpp"

View File

@ -0,0 +1,27 @@
Library Versioning
==================
We provide version number macros for identifying the version of LibTorch in use.
Example usage:
.. code-block:: cpp
#include <torch/torch.h>
#include <iostream>
int main() {
std::cout << "PyTorch version: "
<< TORCH_VERSION_MAJOR << "."
<< TORCH_VERSION_MINOR << "."
<< TORCH_VERSION_PATCH << std::endl;
}
This will output something like:
.. code-block:: text
PyTorch version: 1.8.0
.. note::
These macros are only available in PyTorch >= 1.8.0.

View File

@ -0,0 +1,84 @@
# Ideally, there would be a way in Bazel to parse version.txt
# and use the version numbers from there as substitutions for
# an expand_template action. Since there isn't, this silly script exists.
import argparse
import os
def parse_version(version: str) -> (int, int, int):
"""
Parses a version string into (major, minor, patch) version numbers.
Args:
version: Full version number string, possibly including revision / commit hash.
Returns:
An int 3-tuple of (major, minor, patch) version numbers.
"""
# Extract version number part (i.e. toss any revision / hash parts).
version_number_str = version
for i in range(len(version)):
c = version[i]
if not (c.isdigit() or c == "."):
version_number_str = version[:i]
break
return tuple([int(n) for n in version_number_str.split(".")])
def apply_replacements(replacements, text):
"""
Applies the given replacements within the text.
Args:
replacements (dict): Mapping of str -> str replacements.
text (str): Text in which to make replacements.
Returns:
Text with replacements applied, if any.
"""
for (before, after) in replacements.items():
text = text.replace(before, after)
return text
def main(args):
with open(args.version_path) as f:
version = f.read().strip()
(major, minor, patch) = parse_version(version)
replacements = {
"@TORCH_VERSION_MAJOR@": str(major),
"@TORCH_VERSION_MINOR@": str(minor),
"@TORCH_VERSION_PATCH@": str(patch),
}
# Create the output dir if it doesn't exist.
os.makedirs(os.path.dirname(args.output_path), exist_ok=True)
with open(args.template_path) as input:
with open(args.output_path, "w") as output:
for line in input.readlines():
output.write(apply_replacements(replacements, line))
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate version.h from version.h.in template",
)
parser.add_argument(
"--template-path",
required=True,
help="Path to the template (i.e. version.h.in)",
)
parser.add_argument(
"--version-path", required=True, help="Path to the file specifying the version",
)
parser.add_argument(
"--output-path",
required=True,
help="Output path for expanded template (i.e. version.h)",
)
args = parser.parse_args()
main(args)

View File

@ -16,3 +16,4 @@
#include <torch/types.h>
#include <torch/utils.h>
#include <torch/autograd.h>
#include <torch/version.h>

View File

@ -0,0 +1,10 @@
#pragma once
/// Indicates the major version of LibTorch.
#define TORCH_VERSION_MAJOR @TORCH_VERSION_MAJOR@
/// Indicates the minor version of LibTorch.
#define TORCH_VERSION_MINOR @TORCH_VERSION_MINOR@
/// Indicates the patch version of LibTorch.
#define TORCH_VERSION_PATCH @TORCH_VERSION_PATCH@