Skip to content

[Build] fix build issues for native Windows. #4681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

python3kgae
Copy link
Contributor

Add 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 #4659.

For #4661

Copy link

pytorch-bot bot commented Aug 13, 2024

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/4681

Note: Links to docs will display an error until the docs builds have been completed.

❌ 7 New Failures

As of commit 1b8899c with merge base f887d72 (image):

NEW FAILURES - The following jobs have failed:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 13, 2024
@manuelcandales manuelcandales added module: build/install Issues related to the cmake and buck2 builds, and to installing ExecuTorch triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module labels Aug 13, 2024
Copy link
Contributor

@kirklandsign kirklandsign left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Is this PR tested and ready for review? Also for the install_requirements.ps1, it's for windows only?

@python3kgae
Copy link
Contributor Author

Thank you! Is this PR tested and ready for review? Also for the install_requirements.ps1, it's for windows only?

I didn't really do any real tests except make sure the getting-started-setup works under native Windows and WSL.
Will the CI pipeline test cover all tests or there're some tests must be running locally?

And yes, install_requirements.ps1 is for windows only.

Copy link
Contributor

@dbort dbort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking the time to track down and fix all of these issues! I'm generally happy with the approach, but I'd really like to find a way to avoid duplicating so much data and logic from install_requirements.sh.

Will the CI pipeline test cover all tests or there're some tests must be running locally?

Unfortunately the CI pipeline doesn't cover install_requirements.sh right now. If you can, please try running it on a linux and/or mac with your changes. If you don't have access to either, let us know, and we can help testing.

@@ -15,6 +15,11 @@
#include <cstddef> // size_t
#include <limits>

#ifdef _WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary since platform/compiler.h has the same logic.

If this needed to happen because one of the headers between here and line 29 refer to ssize_t, then the header that needs it should also include compiler.h.

But in general, compiler.h is the only place in the ET code that is allowed to have system-specific checks like #ifdef _WIN32

setup.py Outdated
@@ -508,6 +508,9 @@ def run(self):
item for item in os.environ["CMAKE_BUILD_ARGS"].split(" ") if item
]

if os.name == "nt":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment explaining what this does, and why it's only necessary on windows. If it would be safe to use this flag on all systems, I'd rather remove the nt check.

setup.py Outdated
Comment on lines 561 to 562
debug = os.environ.get("DEBUG", 0)
cfg = "Debug" if debug else "Release"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than duplicating this logic, please hoist it (and the other example near line 435) into a common global function like get_build_type() -> str

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added get_build_type.

setup.py Outdated
)
if os.name == "nt":
ext_modules.append(
BuiltFile(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather extend BuiltFile to handle this situation in a common way, instead of manually repeating the pattern for every entry.

E.g., it could take an extra is_executable: bool = False param that could be set to true here, letting it know to add the .exe suffix on windows.

And we could embed a CMAKE_BUILD_TYPE (debug vs release) placeholder in the paths that is ignored on non-windows systems. How about

third-party/flatbuffers/%BUILD_TYPE%/flatc

Then, on windows systems we can replace %BUILD_TYPE% with get_build_type(), and on non-windows systems we can delete the string %BUILD_TYPE%/ from the path if present.

So this this entry could become

        ext_modules.append(
            BuiltFile(
                "third-party/flatbuffers/%BUILD_TYPE%/flatc",
                "executorch/data/bin/",
                is_executable=True,
            )
        )

And entries below can use the %BUILD_TYPE% placeholder, and use .* to match .so/.dll/.dylib on different systems.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@@ -17,7 +17,11 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really want to avoid _WIN32 checks in any of the code, but this is reasonable for now. The best solution would be to avoid using POSIX concepts and to just use the standard C APIs.

Suggested change
#ifndef _WIN32
// TODO: Rewrite FileDataLoader to use standard C FILE* instead of POSIX file
// descriptors, so that we don't need this _WIN32 check.
#ifndef _WIN32

@python3kgae
Copy link
Contributor Author

Thank you for taking the time to track down and fix all of these issues! I'm generally happy with the approach, but I'd really like to find a way to avoid duplicating so much data and logic from install_requirements.sh.

Will the CI pipeline test cover all tests or there're some tests must be running locally?

Unfortunately the CI pipeline doesn't cover install_requirements.sh right now. If you can, please try running it on a linux and/or mac with your changes. If you don't have access to either, let us know, and we can help testing.

Thanks for the review.
To avoid duplicating install_requirements.sh, I’m considering rewriting it in portable Python. I’ll give it a try to see if it works.

I don’t have access to Linux or macOS, so I’ll need help testing it on those platforms once I’ve got install_requirements.py working

@python3kgae python3kgae marked this pull request as draft August 14, 2024 20:39
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
@python3kgae python3kgae marked this pull request as ready for review August 21, 2024 02:15
@python3kgae
Copy link
Contributor Author

Updated based on the comments.
Tested install_requirements.sh on WSL and install_requirements.bat on Windows.
Need help to test Linux and Mac.

Copy link
Contributor

@dbort dbort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great!

Consider splitting this into some smaller PRs. E.g. we can probably merge the setup.py stuff pretty quickly, but the FileDataLoader might take longer. And, in general, we prefer to have smaller self-contained PRs.

@@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should begin with a capital letter. And I suggest making this a little more general.

Suggested change
# avoid def flat.exe() on windows.
# Remove .exe suffix on windows.

@@ -17,7 +17,11 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads up that #4760 merged recently, which changes this class to use pread(), which I think will break windows. It might make sense to write a separate WindowsFileDataLoader.

There would be a lot of duplicated code, though. If we needed to split into a windows-specific data loader, it might make sense to have an AbstractFileDataLoader with one pure-virtual protected method to do the actual read.

@@ -83,6 +83,10 @@ def python_is_compatible():
print(f"Error: Unknown option {arg}")
sys.exit(1)

# Use ClangCL on Windows.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment repeats what the code does, and doesn't provide extra value. Either remove it, or (ideally) add a comment explaining why this logic is necessary. It'd also be helpful to explain what ClangCL is, since non-windows devs will not be familiar with it.

Comment on lines +136 to +141
#ifndef _WIN32
#include <sys/types.h> // TODO(T126923429): Include size_t, ssize_t
#else
#include <stddef.h>
using ssize_t = ptrdiff_t;
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your PR actually fixes the TODO, so we can remove it.

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

@@ -508,6 +559,8 @@ def run(self):
item for item in os.environ["CMAKE_BUILD_ARGS"].split(" ") if item
]

build_args += ["--config", cfg]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment explaining why this is necessary.

Comment on lines +614 to +616
"third-party/flatbuffers/%BUILD_TYPE%/",
"flatc",
"executorch/data/bin/",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that there are more than two params, please use kwargs for all params. Same for other BuiltFile uses below.

Suggested change
"third-party/flatbuffers/%BUILD_TYPE%/",
"flatc",
"executorch/data/bin/",
src_path="third-party/flatbuffers/%BUILD_TYPE%/",
src_name="flatc",
dst="executorch/data/bin/",

def __init__(self, src: str, dst: str):
def __init__(
self,
src_path: str,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please call this src_dir since it's specifically a directory. src_path sounds like it could still refer to the path to the source file.

ext_modules = []
if ShouldBuild.flatc():
ext_modules.append(
BuiltFile("third-party/flatbuffers/flatc", "executorch/data/bin/")
BuiltFile(
"third-party/flatbuffers/%BUILD_TYPE%/",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will %BUILD_TYPE% always be the final component of the directory path? If so, we could remove the %BUILD_TYPE% placeholder and just add it to the source path inside BuiltFile.

It's ok as-is for now, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, but it does not have access to the installer in the constructor of BuiltFile.
If I understand correctly, obtaining the build configuration requires access to installer.debug.

src: The path to the file to install, relative to the cmake-out
directory. May be an fnmatch-style glob that matches exactly one
file.
src_path: The path to the file to install without name, relative to the cmake-out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please mention %BUILD_TYPE% here and how to use it.

@python3kgae
Copy link
Contributor Author

This is looking great!

Consider splitting this into some smaller PRs. E.g. we can probably merge the setup.py stuff pretty quickly, but the FileDataLoader might take longer. And, in general, we prefer to have smaller self-contained PRs.

Created 7 small PRs. Need more time for FileDataLoader.

@python3kgae
Copy link
Contributor Author

Close after split to small PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: build/install Issues related to the cmake and buck2 builds, and to installing ExecuTorch triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants