Skip to content

Commit

Permalink
[Build] fix build issues for native Windows.
Browse files Browse the repository at this point in the history
Added install_requirements.ps1 for build on native Windows.

Also fix issues block build on native Windows.

1. Get the Windows version of buck2 for Windows.
2. Check the path based on the build configuration for Windows in setup.py.
3. Avoid generating 'def flat.exe()' which is illegal python.
4. Add the Windows version of kernel_link_options.
5. Add links of pthreadpool and cpuinfo for custom_ops_aot_lib.
6. Define ssize_t for Windows.

Still have one link issue tracked with pytorch#4659.

For pytorch#4661
  • Loading branch information
python3kgae committed Aug 13, 2024
1 parent 192d463 commit 4b0140b
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 24 deletions.
10 changes: 10 additions & 0 deletions build/Utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,21 @@ function(macos_kernel_link_options target_name)
)
endfunction()

# Same as kernel_link_options but it's for MSVC linker
function(msvc_kernel_link_options target_name)
target_link_options(
${target_name} INTERFACE
"SHELL:LINKER:/WHOLEARCHIVE:$<TARGET_FILE:${target_name}>"
)
endfunction()

# Ensure that the load-time constructor functions run. By default, the linker
# would remove them since there are no other references to them.
function(target_link_options_shared_lib target_name)
if(APPLE)
macos_kernel_link_options(${target_name})
elseif(MSVC)
msvc_kernel_link_options(${target_name})
else()
kernel_link_options(${target_name})
endif()
Expand Down
4 changes: 3 additions & 1 deletion build/pip_data_bin_init.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ def _find_executable_files_under(dir):
for filename in os.listdir(dir):
filepath = os.path.join(dir, filename)
if os.path.isfile(filepath) and os.access(filepath, os.X_OK):
bin_names.append(filename)
# avoid def flat.exe() on windows.
filename_without_ext = os.path.splitext(filename)[0]
bin_names.append(filename_without_ext)
return bin_names

# The list of binaries to create wrapper functions for.
Expand Down
17 changes: 13 additions & 4 deletions build/resolve_buck.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import platform
import stat
import sys
import tempfile
import urllib.request

from dataclasses import dataclass
Expand Down Expand Up @@ -85,6 +84,12 @@ class BuckInfo:
archive_name="buck2-x86_64-apple-darwin.zst",
target_versions=["3eb1ae97ea963086866b4d2d9ffa966d"],
),
("windows", "x86_64"): BuckInfo(
archive_name="buck2-x86_64-pc-windows-msvc.exe.zst",
target_versions=[
"bf1685c4c4ddd9de4592b5a955cb7326fd01e6c4d5f561643422bed961a17401"
],
),
}


Expand Down Expand Up @@ -135,6 +140,8 @@ def resolve_buck2(args: argparse.Namespace) -> Union[str, int]:
os_family = "linux"
elif sys.platform.startswith("darwin"):
os_family = "darwin"
elif sys.platform.startswith("win"):
os_family = "windows"

platform_key = (os_family, arch)
if platform_key not in BUCK_PLATFORM_MAP:
Expand Down Expand Up @@ -193,12 +200,12 @@ def resolve_buck2(args: argparse.Namespace) -> Union[str, int]:

buck2_archive_url = f"https://github.com/facebook/buck2/releases/download/{target_buck_version}/{buck_info.archive_name}"

with tempfile.NamedTemporaryFile() as archive_file:
try:
print(f"Downloading buck2 from {buck2_archive_url}...", file=sys.stderr)
urllib.request.urlretrieve(buck2_archive_url, archive_file.name)
archive_file, _ = urllib.request.urlretrieve(buck2_archive_url)

# Extract and chmod.
with open(archive_file.name, "rb") as f:
with open(archive_file, "rb") as f:
data = f.read()
decompressed_bytes = zstd.decompress(data)

Expand All @@ -207,6 +214,8 @@ def resolve_buck2(args: argparse.Namespace) -> Union[str, int]:

file_stat = os.stat(buck2_local_path)
os.chmod(buck2_local_path, file_stat.st_mode | stat.S_IEXEC)
finally:
os.remove(archive_file)

return buck2_local_path

Expand Down
13 changes: 13 additions & 0 deletions extension/data_loader/file_data_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h>
#endif

#ifdef _WIN32
#include <stddef.h>
using ssize_t = ptrdiff_t;
#endif

#include <executorch/runtime/core/error.h>
#include <executorch/runtime/core/result.h>
Expand Down Expand Up @@ -58,6 +67,10 @@ FileDataLoader::~FileDataLoader() {
std::free(const_cast<char*>(file_name_));
// fd_ can be -1 if this instance was moved from, but closing a negative fd is
// safe (though it will return an error).
#ifdef _WIN32
if (fd_ == -1)
return;
#endif
::close(fd_);
}

Expand Down
3 changes: 3 additions & 0 deletions extension/llm/custom_ops/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ if(EXECUTORCH_BUILD_KERNELS_CUSTOM_AOT)
endif()

target_link_libraries(custom_ops_aot_lib PUBLIC cpublas torch)
if(WIN32)
target_link_libraries(custom_ops_aot_lib PUBLIC pthreadpool cpuinfo)
endif()
target_compile_options(
custom_ops_aot_lib
PUBLIC -Wno-deprecated-declarations -fPIC -frtti -fexceptions
Expand Down
5 changes: 5 additions & 0 deletions runtime/core/exec_aten/util/tensor_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
#include <cstddef> // size_t
#include <limits>

#ifdef _WIN32
#include <stddef.h>
using ssize_t = ptrdiff_t;
#endif

#include <executorch/runtime/core/array_ref.h>
#include <executorch/runtime/core/error.h>
#include <executorch/runtime/core/exec_aten/exec_aten.h>
Expand Down
5 changes: 5 additions & 0 deletions runtime/core/portable_type/tensor_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@

#pragma once

#ifndef _WIN32
#include <sys/types.h> // TODO(T126923429): Include size_t, ssize_t
#else
#include <stddef.h>
using ssize_t = ptrdiff_t;
#endif

#include <executorch/runtime/core/array_ref.h>
#include <executorch/runtime/core/error.h>
Expand Down
68 changes: 49 additions & 19 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ def src_path(self, installer: "InstallerBuildExt") -> Path:
installer: The InstallerBuildExt instance that is installing the
file.
"""
# TODO(dbort): share the cmake-out location with CustomBuild. Can get a
# handle with installer.get_finalized_command('build')
cmake_cache_dir: Path = Path().cwd() / installer.build_temp / "cmake-out"
# share the cmake-out location with CustomBuild.
# Get a handle with installer.get_finalized_command('build')
cmake_cache_dir = Path(installer.get_finalized_command("build").cmake_cache_dir)

# Construct the full source path, resolving globs. If there are no glob
# pattern characters, this will just ensure that the source file exists.
Expand Down Expand Up @@ -397,7 +397,7 @@ def __init__(self):
self.saved_env = {}

def __enter__(self):
if os.geteuid() == 0 and "HOME" in os.environ:
if os.name != "nt" and os.geteuid() == 0 and "HOME" in os.environ:
log.info("temporarily unsetting HOME while running as root")
self.saved_env["HOME"] = os.environ.pop("HOME")
return self
Expand Down Expand Up @@ -508,6 +508,9 @@ def run(self):
item for item in os.environ["CMAKE_BUILD_ARGS"].split(" ") if item
]

if os.name == "nt":
build_args += ["--config", cfg]

# Put the cmake cache under the temp directory, like
# "pip-out/temp.<plat>/cmake-out".
cmake_cache_dir = os.path.join(repo_root, self.build_temp, "cmake-out")
Expand Down Expand Up @@ -545,6 +548,8 @@ def run(self):
"build/pip_data_bin_init.py.in",
os.path.join(bin_dir, "__init__.py"),
)
# share the cmake-out location with _BaseExtension.
self.cmake_cache_dir = cmake_cache_dir

# Finally, run the underlying subcommands like build_py, build_ext.
build.run(self)
Expand All @@ -553,11 +558,21 @@ def run(self):
def get_ext_modules() -> List[Extension]:
"""Returns the set of extension modules to build."""

debug = os.environ.get("DEBUG", 0)
cfg = "Debug" if debug else "Release"

ext_modules = []
if ShouldBuild.flatc():
ext_modules.append(
BuiltFile("third-party/flatbuffers/flatc", "executorch/data/bin/")
)
if os.name == "nt":
ext_modules.append(
BuiltFile(
f"third-party/flatbuffers/{cfg}/flatc.exe", "executorch/data/bin/"
)
)
else:
ext_modules.append(
BuiltFile("third-party/flatbuffers/flatc", "executorch/data/bin/")
)

if ShouldBuild.pybindings():
ext_modules.append(
Expand All @@ -569,20 +584,35 @@ def get_ext_modules() -> List[Extension]:
)
)
if ShouldBuild.llama_custom_ops():
ext_modules.append(
# Install the prebuilt library for custom ops used in llama.
BuiltFile(
"extension/llm/custom_ops/libcustom_ops_aot_lib.*",
"executorch/extension/llm/custom_ops/",
if os.name == "nt":
ext_modules.append(
BuiltFile(
f"extension/llm/custom_ops/{cfg}/custom_ops_aot_lib.dll",
"executorch/extension/llm/custom_ops",
)
)
)
ext_modules.append(
# Install the prebuilt library for quantized ops required by custom ops.
BuiltFile(
"kernels/quantized/libquantized_ops_aot_lib.*",
"executorch/kernels/quantized/",
ext_modules.append(
# Install the prebuilt library for quantized ops required by custom ops.
BuiltFile(
f"kernels/quantized/{cfg}/quantized_ops_aot_lib.dll",
"executorch/kernels/quantized/",
)
)
else:
ext_modules.append(
# Install the prebuilt library for custom ops used in llama.
BuiltFile(
"extension/llm/custom_ops/libcustom_ops_aot_lib.*",
"executorch/extension/llm/custom_ops/",
)
)
ext_modules.append(
# Install the prebuilt library for quantized ops required by custom ops.
BuiltFile(
"kernels/quantized/libquantized_ops_aot_lib.*",
"executorch/kernels/quantized/",
)
)
)

# Note that setuptools uses the presence of ext_modules as the main signal
# that a wheel is platform-specific. If we install any platform-specific
Expand Down

0 comments on commit 4b0140b

Please sign in to comment.