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

Introduce a dependency on Abseil #1183

Closed
wants to merge 13 commits into from
Closed

Introduce a dependency on Abseil #1183

wants to merge 13 commits into from

Conversation

mtrofin
Copy link
Contributor

@mtrofin mtrofin commented Jun 22, 2021

The main motivation is enabling the benchmark library to play well with
hosts that use Abseil, especially for command line flag functionality.
This also opens up the possibility of reusing functionality such as
string utils, concurrency, or logging.

This was previously discussed in issue #910. This patch:

  • adds the dependency to Abseil. The library will either be downloaded
    (at a fixed, specific commit) or the user may specify their own location
    via the ABSEIL_PATH cmake flag

  • replaces flag functionality with Abseil's.

@google-cla google-cla bot added the cla: yes label Jun 22, 2021
@dmah42
Copy link
Member

dmah42 commented Jun 23, 2021

I think you need to add a bazel dependency on @com_google_absl in the BUILD file.

cmake/Abseil.cmake Outdated Show resolved Hide resolved
set(ABSL_ENABLE_INSTALL ON)
if (NOT (DEFINED ABSEIL_PATH))
message("ABSEIL_PATH not provided. Downloading.")
FetchContent_Declare(
Copy link
Member

Choose a reason for hiding this comment

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

added in 3.11 and we don't require that (to support older linux distributions).

i think you want to follow what the GoogleTest.cmake script does.

Copy link
Member

Choose a reason for hiding this comment

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

#603 for the last discussion about bumping cmake versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ugh. Lots of cmake wizardry. Got it.

#define DEFINE_kvpairs(name, default_val) \
std::map<std::string, std::string> FLAG(name) = \
benchmark::KvPairsFromEnv(#name, default_val)

namespace benchmark {
Copy link
Member

Choose a reason for hiding this comment

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

do we need the rest of this file?

we used to set the default values from the environment... does abseil do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can look into it, my plan was to tackle any more involved logic as a subsequent step; e.g. flag validation (as well as kvpairs)

src/perf_counters.cc Outdated Show resolved Hide resolved
@mtrofin
Copy link
Contributor Author

mtrofin commented Jun 24, 2021

Punting this to when we move past Ubuntu 14.04 LTS - absl requires a compiler version higher than the version of either gnu/clang on that Linux distro.

@mtrofin mtrofin closed this Jun 24, 2021
@oontvoo
Copy link
Member

oontvoo commented Jul 29, 2021

Hi, any idea on exactly when it would be that we move past Ubuntu 14.04 LTS?
It's a pretty old version of ubuntu by now

This patch would benefit a lot of things internally.
Thanks

@dmah42
Copy link
Member

dmah42 commented Sep 20, 2021

https://google.github.io/benchmark/dependencies.html

i believe we can move past 14.04 at this point by quite some way. perhaps we can even drop support for older compilers...

@dmah42
Copy link
Member

dmah42 commented Sep 28, 2021

we now have updated the dependencies, if someone wants to have another go at this. it will up the compiler version, which may mean the removal of some bots that test older versions.

@mtrofin
Copy link
Contributor Author

mtrofin commented Sep 28, 2021

I can resurrect the patch.

The main motivation is enabling the benchmark library to play well with
hosts that use Abseil, especially for command line flag functionality.
This also opens up the possibility of reusing functionality such as
string utils, concurrency, or logging.

This was previously discussed in issue google#910. This patch:

- adds the dependency to Abseil. The library will either be downloaded
(at a fixed, specific commit) or the user may specify their own location
via the ABSEIL_PATH cmake flag

- replaces flag functionality with Abseil's.
@mtrofin
Copy link
Contributor Author

mtrofin commented Sep 28, 2021

reopening

@@ -9,11 +10,10 @@ http_archive(
sha256 = "d7dc12c1d5bc1a87474de8e3d17b7731a4dcebcfb8aa3990fe8ac7734ef12f2f",
)

http_archive(
git_repository(
Copy link
Member

Choose a reason for hiding this comment

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

@@ -1338,7 +1341,6 @@ class Fixture : public internal::Benchmark {
#define BENCHMARK_MAIN() \
int main(int argc, char** argv) { \
::benchmark::Initialize(&argc, argv); \
Copy link
Member

Choose a reason for hiding this comment

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

to replicate the previous behaviour we should check that the returned vector is empty.


auto unparsed = absl::ParseCommandLine(*argc, argv);
*argc = static_cast<int>(unparsed.size());
benchmark::internal::ValidateCommandLineFlags();
Copy link
Member

Choose a reason for hiding this comment

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

nit: don't need the benchmark:: prefix here

#else
#define THREAD_ANNOTATION_ATTRIBUTE_(x) // no-op
#endif
#define THREAD_ANNOTATION_ATTRIBUTE_ THREAD_ANNOTATION_ATTRIBUTE__
Copy link
Member

Choose a reason for hiding this comment

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

Not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

keeps the changes below simpler. If you prefer, I can remove it and replace THREAD_ANNOTATION_ATTRIBUTE_ with THREAD_ANNOTATION_ATTRIBUTE__

Copy link
Member

Choose a reason for hiding this comment

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

if it's not too much trouble, perhaps it'd be great to do that (since you're already overhauling things here) :)
(Optional request, though)

bool, benchmark_list_tests, false,
"Print a list of benchmarks. This option overrides all other options.");

ABSL_FLAG(std::string, benchmark_filter, ".",
Copy link
Member

Choose a reason for hiding this comment

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

Please change this back to "" (empty).

(We intentionally changed this from "." (ie all) to empty (no benchmarks )to support various internal users)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry, must have missed it in the rebase (was going to do a read-over, but wanted to make sure I resurrect the pull first). Thanks for catching this!

@LebedevRI
Copy link
Collaborator

@mtrofin since you are the one who last updated benchmark in llvm, i feel like this question is uniquely suited for you:
how do you envision the future of the library in llvm?

@mtrofin
Copy link
Contributor Author

mtrofin commented Sep 28, 2021

@mtrofin since you are the one who last updated benchmark in llvm, i feel like this question is uniquely suited for you: how do you envision the future of the library in llvm?

Not sure that qualifies me in any particular way, so apologies if the following will disappoint :) Also, if it's unrelated to this patch, we can probably start a thread on llvm-discuss or wherever it'd be more appropriate for llvm-test-suite. I remember someone (maybe you) pointing out there are other copies in llvm elsewhere, so maybe we should talk within the community about consolidating them, if there's value in that.

To try and answer your question; for context, I pulled it in llvm-test-suite for 2 reasons: the main one was that I wanted to leverage perf-counters for experiments. The second was the observation that folks were making changes here and then cherry-picking them over to the llvm-test-suite copy, but other features / fixes weren't pulled over to llvm-test-suite (so more code divergence, which seemed like 'a bad thing'). This gives me the limited perspective through which I'd say we'd keep the llvm-test-suite copy sync-ed whenever folks in the second group wanted new features enabled.

This doesn't address the multiple copies of benchmark in llvm, though, nor does it have a reasoned position as to why do it this way (i.e. pull when needed), other than that 'it's similar in spirit to how it's been done so far' (with the benefit of not adding to code divergence). So maybe a more appropriate way would be to sync periodically? WDYT?

@LebedevRI
Copy link
Collaborator

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

@oontvoo
Copy link
Member

oontvoo commented Sep 28, 2021

I'm asking because my opinion on this change keeps fluctuating between:

@mtrofin since you are the one who last updated benchmark in llvm, i feel like this question is uniquely suited for you:
how do you envision the future of the library in llvm?

On related topic, with this patch going in, doesn't it mean you'd have to get absl as an LLVM's dependency too? (it isn't nowadays, for various reasons). ... may've opened up a can of worms 🤔

@mtrofin
Copy link
Contributor Author

mtrofin commented Sep 28, 2021

I'm asking because my opinion on this change keeps fluctuating between:
@mtrofin since you are the one who last updated benchmark in llvm, i feel like this question is uniquely suited for you:
how do you envision the future of the library in llvm?

On related topic, with this patch going in, doesn't it mean you'd have to get absl as an LLVM's dependency too? (it isn't nowadays, for various reasons). ... may've opened up a can of worms 🤔

The dependency would kick in if LLVM_BUILD_BENCHMARKS were enabled; by default, it'd be downloaded as a build dependency.

So I think there would be at least 2 problems:

  • for folks that want LLVM_BUILD_BENCHMARKS on, but don't want auto-downloads;
  • if there are build issues or other issues you mentioned
    not sure what the precedent is for the former; on the latter, do you know what the issues may be?

@oontvoo
Copy link
Member

oontvoo commented Sep 29, 2021

I'm asking because my opinion on this change keeps fluctuating between:
@mtrofin since you are the one who last updated benchmark in llvm, i feel like this question is uniquely suited for you:
how do you envision the future of the library in llvm?

On related topic, with this patch going in, doesn't it mean you'd have to get absl as an LLVM's dependency too? (it isn't nowadays, for various reasons). ... may've opened up a can of worms 🤔

The dependency would kick in if LLVM_BUILD_BENCHMARKS were enabled; by default, it'd be downloaded as a build dependency.

So I think there would be at least 2 problems:

  • for folks that want LLVM_BUILD_BENCHMARKS on, but don't want auto-downloads;
  • if there are build issues or other issues you mentioned
    not sure what the precedent is for the former; on the latter, do you know what the issues may be?

Nothing concrete ( was thinking of the supported gcc versions ... abseil seems to stop support older gcc sooner but looking at the llvm's doc now, it's basically the same).
So nothing that I can see yet :)

@dmah42
Copy link
Member

dmah42 commented Sep 30, 2021

note: you'll need to remove those failing actions if we can't support 14.04/16.04 any more.

@mtrofin
Copy link
Contributor Author

mtrofin commented Sep 30, 2021

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

I see - IIUC, you're not pushing back with the abseil adoption, but (combining with what @oontvoo was saying) we should consider what we do with the other copy in llvm.

@dominichamon, I think we should circle up to llvm-dev the abseil dep, because of the potential impact to the llvm-proper package. I'll start a thread.

@dmah42
Copy link
Member

dmah42 commented Sep 30, 2021

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

I see - IIUC, you're not pushing back with the abseil adoption, but (combining with what @oontvoo was saying) we should consider what we do with the other copy in llvm.

@dominichamon, I think we should circle up to llvm-dev the abseil dep, because of the potential impact to the llvm-proper package. I'll start a thread.

sgtm

@oontvoo
Copy link
Member

oontvoo commented Sep 30, 2021

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

I see - IIUC, you're not pushing back with the abseil adoption, but (combining with what @oontvoo was saying) we should consider what we do with the other copy in llvm.
@dominichamon, I think we should circle up to llvm-dev the abseil dep, because of the potential impact to the llvm-proper package. I'll start a thread.

sgtm

+1

message("ABSEIL_PATH not provided. Downloading.")
set(ABSEIL_PREFIX "${benchmark_BINARY_DIR}/third_party/abseil")
configure_file(${benchmark_SOURCE_DIR}/cmake/Abseil.cmake.in ${ABSEIL_PREFIX}/CMakeLists.txt @ONLY)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .

Choose a reason for hiding this comment

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

This doesn't pass through CMake options to the Abseil build and instead relies on defaults. For example, CMake will use /usr/bin/cc and /usr/bin/c++ as the default compiler on UNIX-like systems but that may be undesirable. In our case, it's going to fail because those binaries don't exists on our bots at all. Rather, we always specify the compiler manually via CMAKE_C_COMPILER and CMAKE_CXX_COMPILER. The same applies to all other tools. Ideally we would pass all of these variables from the benchmark build to the abseil build.

Copy link
Member

Choose a reason for hiding this comment

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

worth mentioning that other deps in this repo(eg., GoogleTest) also doesn't pass through any build options.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. Would that be addressed if we bumped cmake version requirement to 3.11, and thus allow us to use ExternalProject_Add?

if (NOT (DEFINED ABSEIL_PATH))
message("ABSEIL_PATH not provided. Downloading.")
set(ABSEIL_PREFIX "${benchmark_BINARY_DIR}/third_party/abseil")
configure_file(${benchmark_SOURCE_DIR}/cmake/Abseil.cmake.in ${ABSEIL_PREFIX}/CMakeLists.txt @ONLY)

Choose a reason for hiding this comment

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

What's the motivation for using the template here rather than including ExternalProject_Add here directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

see #1183 (review)
(cmake version issues)

@gjasny
Copy link
Contributor

gjasny commented Oct 6, 2021

Hello,

some time ago I noticed that an LTS abseil used within my project and the webrtc abseil version generate the same symbols despite the goal of abseil to make LTS versions co-linkable with other abseil versions. The filed issue abseil/abseil-cpp#851 does not see much traction.

I could imagine that as long as the issue is not resolved mixing webrtc, grpc, and google-benchmark might lead into an interesting dependency chaos.

Thanks,
Gregor

@mtrofin
Copy link
Contributor Author

mtrofin commented Oct 11, 2021

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

I see - IIUC, you're not pushing back with the abseil adoption, but (combining with what @oontvoo was saying) we should consider what we do with the other copy in llvm.
@dominichamon, I think we should circle up to llvm-dev the abseil dep, because of the potential impact to the llvm-proper package. I'll start a thread.

sgtm

+1

LLVM folks were concerned with an abseil dependency, and folks here (e.g. @gjasny being the last one) expressed concerns, too.

@oontvoo, what was the main motivation you'd benefit from the abseil dep? @LebedevRI , you also mentioned a potential upside; @dominichamon , IIRC the main problem we hit when pulling in our repo was around flags, is that correct?

Would this alternative work (@dominichamon , I think you suggested it earlier): we don't require abseil as a dependency; but we factor the problematic APIs, and add build option, such that, if the user has abseil, we use that, else we use our copy. We can start with the problem APIs (flags, and flag macros), and can potentially extend to stuff like string utils and concurrency, but in the same way.

I'd specifically imagine either a subfolder under a third_party one, where we either fork the files we need, or something similar (copy / heavily edit, if compat is hurt)

So this wouldn't require changing the compat matrix. It would require a compat statement as to which version of abseil is known to work (in the case where the user has one and wants to use it instead), and we'd need to add a bot for that.

WDYT?

@LebedevRI
Copy link
Collaborator

@LebedevRI , you also mentioned a potential upside

My upside was that i would not have to upstream my changes the library once i fork it over this dependency.
Somehow i suspect i'm not the only one, uhm, unhappy about the proposed dependency,
so llvm and whoever else are welcomed to switch upstreams.

For the life of me, i just don't understand why google thinks that forcing changes down people's throats
is a good strategy, but then this is by far not the first time it happens (see numerous google chrome fiaskos).

@mtrofin
Copy link
Contributor Author

mtrofin commented Oct 11, 2021

@LebedevRI , you also mentioned a potential upside

My upside was that i would not have to upstream my changes the library once i fork it over this dependency. Somehow i suspect i'm not the only one, uhm, unhappy about the proposed dependency, so llvm and whoever else are welcomed to switch upstreams.

For the life of me, i just don't understand why google thinks that forcing changes down people's throats is a good strategy, but then this is by far not the first time it happens (see numerous google chrome fiaskos).

I think we're moving past proposing this dependency, and exploring alternatives that address what motivated it in the first place, without having it as a requirement. IIUC, you'd be fine with such an alternative?

@oontvoo
Copy link
Member

oontvoo commented Oct 11, 2021

@oontvoo, what was the main motivation you'd benefit from the abseil dep? [...] @dominichamon , IIRC the main problem we hit when pulling in our repo was around flags, is that correct?

The #1 motivation was flags, yes. (Internally we have an ABSL_FLAG --benchmark_filter, whereas the OSS benchmark here uses its own facility)

Additionally, there are other features from absl that we could benefit, (for eg., most recently: #1230 )

@oontvoo
Copy link
Member

oontvoo commented Oct 11, 2021

P.S: I should add that the flag motivation wasn't just a "nice to have" feature - it's almost (*) a requirement for us to switch entirely to the OSS benchmark internally.

(*) of course, there's some hack to get around it - but it'd be great if we could avoid it. As you know, we've already got 2 types of flags (the old command line flags and the newer ABSL_FLAGs)

@dmah42
Copy link
Member

dmah42 commented Oct 11, 2021

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

I see - IIUC, you're not pushing back with the abseil adoption, but (combining with what @oontvoo was saying) we should consider what we do with the other copy in llvm.
@dominichamon, I think we should circle up to llvm-dev the abseil dep, because of the potential impact to the llvm-proper package. I'll start a thread.

sgtm

+1

LLVM folks were concerned with an abseil dependency, and folks here (e.g. @gjasny being the last one) expressed concerns, too.

@oontvoo, what was the main motivation you'd benefit from the abseil dep? @LebedevRI , you also mentioned a potential upside; @dominichamon , IIRC the main problem we hit when pulling in our repo was around flags, is that correct?

yes though i've worked around that for the most part, but as @oontvoo has suggested already, it's not a great workaround, requiring flags to be plumbed through to benchmark's own flag system instead of using the de facto default ABSL flags.

there's a longer term view of simplifying benchmark to focus on benchmarking...

Would this alternative work (@dominichamon , I think you suggested it earlier): we don't require abseil as a dependency; but we factor the problematic APIs, and add build option, such that, if the user has abseil, we use that, else we use our copy. We can start with the problem APIs (flags, and flag macros), and can potentially extend to stuff like string utils and concurrency, but in the same way.

i think that would be great. it would mean we'd need to keep "our" version in sync with any upstream API changes from third party but that's manageable, i think. i mean, we already manage with things like this...

my concern is it's adding complexity when the long term view should be to reduce complexity. if there's no actual need for abseil, let's just drop it and keep things simple.

I'd specifically imagine either a subfolder under a third_party one, where we either fork the files we need, or something similar (copy / heavily edit, if compat is hurt)

So this wouldn't require changing the compat matrix. It would require a compat statement as to which version of abseil is known to work (in the case where the user has one and wants to use it instead), and we'd need to add a bot for that.

WDYT?

@mtrofin
Copy link
Contributor Author

mtrofin commented Oct 11, 2021

I'm asking because my opinion on this change keeps fluctuating between:

  • meh, i'll manage
  • this greatly simplifies upstreaming for changes! (i.e. either soft fork or hard fork)

I see - IIUC, you're not pushing back with the abseil adoption, but (combining with what @oontvoo was saying) we should consider what we do with the other copy in llvm.
@dominichamon, I think we should circle up to llvm-dev the abseil dep, because of the potential impact to the llvm-proper package. I'll start a thread.

sgtm

+1

LLVM folks were concerned with an abseil dependency, and folks here (e.g. @gjasny being the last one) expressed concerns, too.
@oontvoo, what was the main motivation you'd benefit from the abseil dep? @LebedevRI , you also mentioned a potential upside; @dominichamon , IIRC the main problem we hit when pulling in our repo was around flags, is that correct?

yes though i've worked around that for the most part, but as @oontvoo has suggested already, it's not a great workaround, requiring flags to be plumbed through to benchmark's own flag system instead of using the de facto default ABSL flags.

there's a longer term view of simplifying benchmark to focus on benchmarking...

Would this alternative work (@dominichamon , I think you suggested it earlier): we don't require abseil as a dependency; but we factor the problematic APIs, and add build option, such that, if the user has abseil, we use that, else we use our copy. We can start with the problem APIs (flags, and flag macros), and can potentially extend to stuff like string utils and concurrency, but in the same way.

i think that would be great. it would mean we'd need to keep "our" version in sync with any upstream API changes from third party but that's manageable, i think. i mean, we already manage with things like this...

my concern is it's adding complexity when the long term view should be to reduce complexity. if there's no actual need for abseil, let's just drop it and keep things simple.

SGTM, looks like this PR can be closed, and start a different one along the lines above.

I'd specifically imagine either a subfolder under a third_party one, where we either fork the files we need, or something similar (copy / heavily edit, if compat is hurt)
So this wouldn't require changing the compat matrix. It would require a compat statement as to which version of abseil is known to work (in the case where the user has one and wants to use it instead), and we'd need to add a bot for that.
WDYT?

@mtrofin mtrofin closed this Oct 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants