Skip to content
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

Add ability to build with Clang #507

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

p-senichenkov
Copy link
Collaborator

@p-senichenkov p-senichenkov commented Dec 23, 2024

Make Desbordante be able to be built with Clang on Linux and LLVM/Apple CLang on macOS:

  • Make some changes to build.sh and CMakeLists.txt (bump versions of some libraries and workaround some Clang bugs)
  • Fix warnings, UB and address issues, that GCC hasn't found and Clang has
  • Update "build" section in README.md
  • Get rid of GCC intrinsics
  • Fix some implementation-defined behaviour
  • Add corresponding tests to CI
    See commit descriptions for more information

@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from dac18fc to 2108d8a Compare January 3, 2025 11:30
@p-senichenkov p-senichenkov marked this pull request as ready for review January 3, 2025 11:31
@Vdaleke Vdaleke self-requested a review January 3, 2025 14:54
Copy link
Collaborator

@Vdaleke Vdaleke 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 your great work. I'm not completely done with the review yet and there will probably be more comments soon, but I'll post these so you can start fixing them.

I will leave a few comments that cannot be attached to individual files:

  1. There are no binding-tests for Clang and macOS Apple Clang. And there may be problems similar to those that caused the Fix CMakeLists.txt, macOS guide and refactor .gitignore  #492, I mean DYLD_PATH on macOS.

  2. We keep a short commit history. Pls, squash commits to some parts. I propose squash into 4 like this: CI, src-fixing, CMake, README.

  3. You made great descriptions for all commits, pls copy them in some way to PR description. If someone else looks at the PR, they don't look for commit descriptions, and it's also a good way to present the result.

.github/composite-actions/download-libraries/action.yml Outdated Show resolved Hide resolved
.github/workflows/core-tests.yml Outdated Show resolved Hide resolved
build.sh Show resolved Hide resolved
.github/composite-actions/download-libraries/action.yml Outdated Show resolved Hide resolved
.github/composite-actions/download-libraries/action.yml Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
.github/workflows/core-tests.yml Outdated Show resolved Hide resolved
@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 4, 2025

image

Interesting checks, maybe somewhere into project settings these names are inlined to block merge without them?

@p-senichenkov
Copy link
Collaborator Author

p-senichenkov commented Jan 4, 2025

Interesting checks, maybe somewhere into project settings these names are inlined to block merge without them?

Yes, it's branch protection rules. I left a comment about it in PR#499

@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 4, 2025

Interesting checks, maybe somewhere into project settings these names are inlined to block merge without them?

Yes, it's branch protection rules. I left a comment about it in PR#499

Oh, I didn't notice there are 2 pull request, is 499 needed at all if this one exists? I suggest closing it and continuing only in this one.

@p-senichenkov
Copy link
Collaborator Author

Oh, I didn't notice there are 2 pull request, is 499 needed at all if this one exists? I suggest closing it and continuing only in this one.

There's 3 pull requests. 499 addresses Clang on Linux, 500 -- LLVM Clang on macOS, and this PR addresses Apple Clang.
499 is a part of 500, and 500 is a part of 507. I recommend to review them in this order.
I think, it's better to have 3 different PRs and try to merge as many of them as possible before the release

@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 4, 2025

Oh, I didn't notice there are 2 pull request, is 499 needed at all if this one exists? I suggest closing it and continuing only in this one.

There's 3 pull requests. 499 addresses Clang on Linux, 500 -- LLVM Clang on macOS, and this PR addresses Apple Clang. 499 is a part of 500, and 500 is a part of 507. I recommend to review them in this order. I think, it's better to have 3 different PRs and try to merge as many of them as possible before the release

I don't like that they are tightly coupled in CI. It seems to me that when all the fixes are already in place, it's easier to do and review everything together, rather than merge one by one, changing the architecture in the process. And do we really need a release without a pip-package on MacOS?

Copy link
Collaborator

@Vdaleke Vdaleke left a comment

Choose a reason for hiding this comment

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

The second part of review.

As for constructors which is in a lot of comments. I heard about the performance of the aggregates from colleagues at work, and constantly. For example, that's why it is not recommended to use a std::pair, for some reason they added a constructor there and a regular handwritten structure will be faster. But I can't find normal proofs on the Internet.

src/core/util/bitset_extensions.cpp Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/maybe_unused.h Outdated Show resolved Hide resolved
src/tests/test_algo_interfaces.cpp Show resolved Hide resolved
src/tests/test_pfdtane.cpp Show resolved Hide resolved
src/tests/test_tane_afd_measures.cpp Show resolved Hide resolved
src/core/util/auto_join_thread.h Show resolved Hide resolved
@p-senichenkov
Copy link
Collaborator Author

As for constructors which is in a lot of comments. I heard about the performance of the aggregates from colleagues at work, and constantly. For example, that's why it is not recommended to use a std::pair, for some reason they added a constructor there and a regular handwritten structure will be faster. But I can't find normal proofs on the Internet.

The only thing I can do is to define constructors conditionnally -- only when aggregate initialization isn't availible.

@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 5, 2025

As for constructors which is in a lot of comments. I heard about the performance of the aggregates from colleagues at work, and constantly. For example, that's why it is not recommended to use a std::pair, for some reason they added a constructor there and a regular handwritten structure will be faster. But I can't find normal proofs on the Internet.

The only thing I can do is to define constructors conditionnally -- only when aggregate initialization isn't availible.

I don't quite understand why you can't just use brace-initialization everywhere?

@p-senichenkov
Copy link
Collaborator Author

I don't quite understand why you can't just use brace-initialization everywhere?

Brace-initialization calls constructor. It won't help if we want to get rid of constructors.

@p-senichenkov
Copy link
Collaborator Author

p-senichenkov commented Jan 6, 2025

In terms of this page on cppreference, apparently, you suggest to use direct-list-initialization (2 variant) instead of copy-list-initialization (7 variant). Maybe this will work -- I'll check it later. But in most cases we have emplace_back, that cannot be replaced with direct-list-initialization.
So, there are still two possible ways:

  • conditionally define constructor
  • conditionally replace emplace_back(arg1, arg2) with push_back(T{arg1, arg2})
    (by "conditionally", I mean using of feature-test macros). As for me, the second way is very bad.

@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 6, 2025

In terms of this page on cppreference,

Not working link

But in most cases we have emplace_back, that cannot be replaced with direct-list-initialization.

Use push_back instead

@p-senichenkov
Copy link
Collaborator Author

@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from be21b26 to eb10e2e Compare January 6, 2025 13:05
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/util/bitset_extensions.h Show resolved Hide resolved
@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from 6fc2ab3 to 1bd7606 Compare January 6, 2025 20:37
@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 6, 2025

Due to ac2ad57.
Let me remind you that at the meeting we agreed to leave in the readme only gcc for Linux and only apple clang for macOS, everything else will move to the wiki.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/algorithms/md/hymd/md_lhs.h Outdated Show resolved Hide resolved
src/core/algorithms/md/hymd/md_lhs.h Outdated Show resolved Hide resolved
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/algorithms/md/hymd/md_lhs.h Outdated Show resolved Hide resolved
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

clang-tidy made some suggestions

src/core/algorithms/dd/split/split.cpp Outdated Show resolved Hide resolved
@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from d09bbbd to 34a9520 Compare January 8, 2025 12:50
- Add `set -e` in build.sh to stop build process on error
- Add SYSTEM property to all `add_subdirectory` commands that add
  external dependencies to avoid compiler warnings that aren't related
  to Desbordante
- Disable alloc-dealloc-mismatch check as it's false positive
  on Ubuntu (see comment in CMakeLists.txt)
- Limit UB sanitizer "function" check to only our code when building with
  Clang on macOS (see comment in CMakeLists.txt)
- Update googletest version from 1.13.0 to 1.14.0, because 1.13.0 produces "narrowing conversion" warning due to a bug
  (issue #4206, google/googletest#4206) when building
  with Clang. This bug was fixed in 1.14.0 (commit 3044657,
  google/googletest@3044657)
- Disable deprecated-declaration warning on Clang-18 (see comment in CMakeLists.txt)
@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from 34a9520 to 859b5c0 Compare January 8, 2025 15:24
@p-senichenkov p-senichenkov requested a review from Vdaleke January 8, 2025 21:11
Copy link
Collaborator

@Vdaleke Vdaleke left a comment

Choose a reason for hiding this comment

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

Thanks for the corrections, it looks much better. I left a couple of minor comments and questions. Of the possible major edits, only replacing action with a composition in CI-tests, if it is possible to catch an incorrect configuration.

.github/composite-actions/install-dependencies/action.yml Outdated Show resolved Hide resolved
.github/workflows/bindings-tests.yml Outdated Show resolved Hide resolved
.github/workflows/bindings-tests.yml Outdated Show resolved Hide resolved
.github/workflows/check-codestyle.yml Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/maybe_unused_on_clang.h Outdated Show resolved Hide resolved
src/tests/test_algo_interfaces.cpp Show resolved Hide resolved
Fix Clang warnings and UB and ADDRESS sanitizer errors:
- Replace INSTANTIATE_TEST_CASE_P, which is deprecated, with INSTANTIATE_TEST_SUITE_P
  in NDVerifier tests
- Mark unused fields as [[maybe_unused]]. Use MAYBE_UNUSED_PRIVATE_FIELD macro, because GCC produces
  warning when [[maybe_unused]] attribute is present, and Clang -- when it isn't.
  (see comment in util/maybe_unused_on_clang.h)
- Convert double literals to model::DoubleType and model::IntType explicitly in tests/test_types.cpp
- Check that column is numeric *before* casting it to INumericType in DataStats::GetMedianAD
- Don't process empty vector in GetPartition in gfd_validation.cpp (immediately return 0)
- Disable tests causing float-to-long cast when result is infinity in tests/test_types.cpp
- Use std::chrono::high_resolution_clock instead of std::chrono::_V2::high_resolution_clock in
  fastod/util/timer.h, because symbol versioning is gcc-specific
- Use &Insert instead of this->Insert in KDTree constructor
- Use system_clock everywhere instead of mix of system_clock and
  high_resolution_clock in Cords::ExecuteInternal
- Add fallback behaviour in hymd::utility::MdLessPairs if operator <=> for vectors isn't availible
- Add explicit #include <string> in exceptions.h
- Add template keyword in CanonicalOD::IsValid to avoid most vexing parse (see cross-platform guide in wiki)
- Explicitly cast kSeed_ to result_type in des/rng.h, because result_type of mt19937 is always 32-bit
  and it's not bound to some built-in integral type
- Use reverse iterators to traverse set in reverse order, instead of
  strange behaviour with direct iterators in egfd_validation.cpp/ReverseConstruction
Add information about other compilers in README.
Extra build instructions (Linux & Clang, macOS & LLVM CLang, macOS & GCC)
are now moved to wiki
@p-senichenkov p-senichenkov requested a review from Vdaleke January 9, 2025 19:20
@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from ca4b7e7 to 35fb7a7 Compare January 9, 2025 20:32
Copy link
Collaborator

@Vdaleke Vdaleke left a comment

Choose a reason for hiding this comment

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

LGTM, just remove FIXME pls

src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
src/core/util/bitset_extensions.h Outdated Show resolved Hide resolved
- Use simple RAII wrapper of std::thread instead of std::jthread when the latter isn't implemented
- Use custom implementations of std::bitset::_Find_first and _Find_next when gcc intrinsics
  aren't availible. Also, implement some utility functions using custom FindFirst and FindNext
Don't use features, which behaviour is implementation-defined and differ
in libstdc++ and libc++. Instead use "stable" versions:
- sort pairs by value if frequencies are equal in Cords' FrequencyHandler::InitFrequencyHandler
- Use std::stable_sort instead of std::sort in DES::GetRandomPopulationInDomainds
- Use std::set instead of std::unordered_set in differential_functions.cpp/GetRandIndices
- Use std::stable_sort in PDFTane::CalculatePFDError instead of std::sort
@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from cfd4b2b to a8814af Compare January 10, 2025 12:00
Copy link
Collaborator

@Vdaleke Vdaleke left a comment

Choose a reason for hiding this comment

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

Sorry for the request after approval, but it seems like an easy way to get rid of the double name in actions.

.github/workflows/bindings-tests.yml Outdated Show resolved Hide resolved
.github/workflows/bindings-tests.yml Outdated Show resolved Hide resolved
.github/workflows/core-tests.yml Outdated Show resolved Hide resolved
.github/workflows/core-tests.yml Outdated Show resolved Hide resolved
@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 12, 2025

I managed to build a pip package for macOS under llvm-clang and now I think that llvm-clan should be the default compiler for macOS because llvm-clang has more extensions and it should be better in performance?
Then I suggest leaving such configurations:

{macos-latest, llvm-clang, Release},
{macos-latest, llvm-clang, Debug},
{macos-latest, llvm-clang, Debug, UB},
{macos-latest, llvm-clang, Debug, Address},
{macos-latest, apple-clang, Release},

The last one to check compatibility with apple clang in terms of extensions and standard support.

And then I think that in the readme we need to insert the assembly configuration under the llvm clang, since we choose it as the main one.

@p-senichenkov
Copy link
Collaborator Author

I managed to build a pip package for macOS under llvm-clang and now I think that llvm-clan should be the default compiler for macOS because llvm-clang has more extensions and it should be better in performance?

Why do you think LLVM Clang will be more effective? The only difference is aggregate initialization, which is corrected anyway. I think, "native" compiler can be better (and can be worse -- we should test it).

However, Apple Clang building instruction are much shorter, as there's no need in compiling boost. Since Apple Clang is pre-installed on macOS, users can build project without much preparation, like with GCC on Linux. I don't think we should place LLVM Clang in README as "main" compiler.

@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 12, 2025

The only difference is aggregate initialization, which is corrected anyway.

No that's not the only difference, llvm clang provides bitset and jthread extensions for which we have provided a replacement that should not be as efficient as the implementation from the clang compiler

However, Apple Clang building instruction are much shorter, as there's no need in compiling boost. Since Apple Clang is pre-installed on macOS, users can build project without much preparation, like with GCC on Linux. I don't think we should place LLVM Clang in README as "main" compiler.

Maybe it's true, but I think it's worth making some kind of annotation that we use llvm-clang as the default compiler for building the pip package and it's worth trying to build using it

@p-senichenkov
Copy link
Collaborator Author

No that's not the only difference, llvm clang provides bitset and jthread extensions for which we have provided a replacement that should not be as efficient as the implementation from the clang compiler

libc++, which is used in any Clang does not provide bitset extensions and thread. See https://en.cppreference.com/w/cpp/compiler_support

Add tests for Clang on Linux, LLVM Clang on macOS and Apple Clang on macOS.
Also, bump boost version used in CI, as 1.8.10 produces an error on macOS with LLVM Clang.
Here it's said that boost 1.85.0 works fine:
bambulab/BambuStudio#3957
Aggregate initialization isn't availible on Apple Clang. Use direct-list-initialization
instead wherewer possible:
- Split::IndexSearchSpace
- MinPickerLattice::AddGeneralizations
- OneByOnePicker::AddGeneralizations
- md_lattice/Specializer
- MdLattice::GetAll
- hymd::LhsNode
-     ::BatchValidator
- SimilarityData::Creator
- BatchValidator::MultiCardPartitionElementProvider
- MD::GetDescription
- order::GetIndexedByteData
- python_bindings::BindOd
- model::DD

Define constructor elsewhere:
- test_algo_interfaces/KeysTestParams
- test_dc_verifier/DCTestParams
- test_ind_verifier/INDVerifierTestConfig
- test_pfdtane/PFDTaneValidationParams
- test_tane_afd_measures/TaneValidationParams
-                       /PdepSelfValidationParams
- test_typed_column_data/TypeParsingParams
@p-senichenkov p-senichenkov force-pushed the apple-clang-buildability branch from c76af53 to 3096622 Compare January 12, 2025 12:28
@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 12, 2025

libc++, which is used in any Clang does not provide bitset extensions and thread.

I don't quite understand, it was necessary to add jthread and the bitset extension only when apple-clang was added. Can't we use libstdc++?

@p-senichenkov
Copy link
Collaborator Author

it was necessary to add jthread and the bitset extension only when apple-clang was added

No, it was necessary even on Linux (see #499)

Can't we use libstdc++?

We can, but there's no point in compiling with Clang, if we link it with GCC's standard library. In that case we could just close this PR without merging.

@Vdaleke
Copy link
Collaborator

Vdaleke commented Jan 12, 2025

it was necessary to add jthread and the bitset extension only when apple-clang was added

No, it was necessary even on Linux (see #499)

Can't we use libstdc++?

We can, but there's no point in compiling with Clang, if we link it with GCC's standard library. In that case we could just close this PR without merging.

now I think that we should supply a pip package built with gcc even on macos, but that's not your concern anymore, maybe I'll add it myself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants