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

Make fastNLO converter part of the CLI #120

Merged
merged 26 commits into from
Mar 16, 2022
Merged

Make fastNLO converter part of the CLI #120

merged 26 commits into from
Mar 16, 2022

Conversation

cschwan
Copy link
Contributor

@cschwan cschwan commented Feb 19, 2022

This implements the suggestion by @alecandido discussed here: #115, following my outline given here: #115 (reply in thread). I tried to keep the changes minimal, and the biggest file is basically copied from the examples directory. You can view the difference here:

--- ../examples/fnlo2pine/fnlo2pine.cpp 2022-01-01 22:37:33.214272784 +0100
+++ src/import/fastnlo.cpp      2022-02-19 11:46:59.233366022 +0100
@@ -1,3 +1,5 @@
+#include "pineappl_cli/src/import/fastnlo.hpp"
+
 #include <cmath>
 #include <cstdlib>
 #include <numeric>
@@ -503,16 +505,8 @@
     return pgrid;
 }

-int main(int argc, char* argv[])
+int this_would_be_main(char const* in, char const* out)
 {
-    if (argc != 3)
-    {
-        return EXIT_FAILURE;
-    }
-
-    std::string in(argv[1]);
-    std::string out(argv[2]);
-
     // TODO: read this from an argument
     uint32_t alpha = 0;

@@ -650,11 +644,13 @@
         }
     }

-    pineappl_grid_write(grids.at(0), out.c_str());
+    pineappl_grid_write(grids.at(0), out);
     pineappl_grid_delete(grids.at(0));

     if (different)
     {
         return 1;
     }
+
+    return 0;
 }

As you can see, I only had to rename the main function, and the argument parsing is now done by clap inside the Rust CLI.

The new subcommand works quite well, but it has the same dependencies as the C++ converter: fastNLO and the PineAPPL C API; the latter is a bit odd given that we use the C and the Rust API at the same time, and this must be improved in the future.

One odd point is that build.rs links fastnlotoolkit statically (with z as a dependency), which I was forced to since linking dynamically it didn't work. I have to investigate why.

Everything is hidden behind the feature import-fastnlo, so you have to compile the CLI using --features import-fastnlo or --all-features. @alecandido do you want to rename import-fastnlo to fastnlo to keep it simple?

@cschwan cschwan added the enhancement New feature or request label Feb 19, 2022
@cschwan cschwan self-assigned this Feb 19, 2022
@alecandido
Copy link
Member

I don't have a neat opinion on import-fastnlo vs fastnlo: no need to be short from my point of view, but actually fastnlo is already not ambiguous, so it's fine as well.

About linking, I will have a look as well, maybe someone wrote something somewhere about it (for sure such a generic statement is true, the problem is that the result of this query will be long).
I know that Rust itself is usually linking all crates statically (so everything but standard library), but everything should be possible somehow.
The reference has a chapter about linkage, I'll take my time for reading it, maybe it's enough. There is also a reference to FFI section at the beginning, might be useful as well.

About the code itself this is exactly what I expected, and I'm very glad it is working.

This is perfect for the first shot, but as you said having to use PineAPPL C API is odd, but I believe there is an easy solution for this: we should move most of the code to the Rust side, leaving more atomic functions in C++, rather than performing the full task on that side.
The moment things will be ported, we'll be left with a converter application in Rust, and essentially Rust bindings for fastNLO.

I would suggest to move the minimal "fastNLO bindings" on a separate crate, inside this repository, as an external contribution and not directly part of PineAPPL CLI (but a dependency of course). Then we might think about publishing it or not on https://crates.io/, but from my point of view this comes at the end, so it's both far in the future and not needed for our main purpose.

@alecandido alecandido self-assigned this Feb 19, 2022
@cschwan
Copy link
Contributor Author

cschwan commented Feb 19, 2022

I don't have a neat opinion on import-fastnlo vs fastnlo: no need to be short from my point of view, but actually fastnlo is already not ambiguous, so it's fine as well.

I changed it to fastnlo in commit 29aa3c5 because I think shorter is better 😄.

About linking, I will have a look as well, maybe someone wrote something somewhere about it (for sure such a generic statement is true, the problem is that the result of this query will be long). I know that Rust itself is usually linking all crates statically (so everything but standard library), but everything should be possible somehow. The reference has a chapter about linkage, I'll take my time for reading it, maybe it's enough. There is also a reference to FFI section at the beginning, might be useful as well.

If you've got the time you could try and see whether you can reproduce my problem. You'll need to install the C API and fastNLO, and then make the following change:

diff --git a/pineappl_cli/build.rs b/pineappl_cli/build.rs
index 0719736..a0d0061 100644
--- a/pineappl_cli/build.rs
+++ b/pineappl_cli/build.rs
@@ -46,8 +46,7 @@ fn main() {
     println!("cargo:rustc-link-search={}", fnlo_lib_path);

     // TODO: why do I have to link statically?
-    println!("cargo:rustc-link-lib=static=fastnlotoolkit");
-    println!("cargo:rustc-link-lib=z");
+    println!("cargo:rustc-link-lib=fastnlotoolkit");

     // bridging code
     bridge.file("src/import/fastnlo.cpp").compile("cxx-bridge");

That should link fastNLO dynamically, but I get lots of linking failures that complain about missing fastNLO symbols.

About the code itself this is exactly what I expected, and I'm very glad it is working.

This is perfect for the first shot, but as you said having to use PineAPPL C API is odd, but I believe there is an easy solution for this: we should move most of the code to the Rust side, leaving more atomic functions in C++, rather than performing the full task on that side. The moment things will be ported, we'll be left with a converter application in Rust, and essentially Rust bindings for fastNLO.

That's exactly the idea!

I would suggest to move the minimal "fastNLO bindings" on a separate crate, inside this repository, as an external contribution and not directly part of PineAPPL CLI (but a dependency of course). Then we might think about publishing it or not on https://crates.io/, but from my point of view this comes at the end, so it's both far in the future and not needed for our main purpose.

That may be a good idea, basically in the same spirit as my LHAPDF crate.

}

#[cfg(not(feature = "fastnlo"))]
fn main() {}
Copy link
Member

@alecandido alecandido Feb 19, 2022

Choose a reason for hiding this comment

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

Two options for the feature gate:

  1. if you like to do what I proposed, and having a separate crate for "fastNLO bindings", than we need to do nothings right now (build.rs will be simply the build file of that crate, and we'll drop the feature gates, the only option will be spelled out in pineappl_cli/Cargo.toml)
  2. if we're going to keep everything in PineAPPL CLI, then you'll need a separate function for the time APPLgrid will join the party (and the feature gate we'll be placed not on main() but on fastNLO())

Personally, I still prefer option 1..

@alecandido
Copy link
Member

This afternoon I'll try to dynamically link.

Trying what you put takes nothing, but I want at least a bit of time to investigate (it's unlikely that doing the same I'll obtain a different result).

@codecov
Copy link

codecov bot commented Feb 19, 2022

Codecov Report

Merging #120 (15a91fe) into master (2197d40) will decrease coverage by 0.05%.
The diff coverage is 0.00%.

❗ Current head 15a91fe differs from pull request most recent head f236fdc. Consider uploading reports for the commit f236fdc to get more accurate results

@@            Coverage Diff             @@
##           master     NNPDF/runcards#120      +/-   ##
==========================================
- Coverage   89.63%   89.57%   -0.06%     
==========================================
  Files          31       32       +1     
  Lines        3088     3090       +2     
==========================================
  Hits         2768     2768              
- Misses        320      322       +2     
Impacted Files Coverage Δ
pineappl_cli/src/import.rs 0.00% <0.00%> (ø)
pineappl_cli/src/main.rs 100.00% <ø> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2197d40...f236fdc. Read the comment docs.

@alecandido
Copy link
Member

I'm first reading references, starting from Linkage.

Being about pure Rust, it's not very useful (it's useful for me to properly understand the rest).
There is a caveat that is worth to mention:

  1. If a static library is being produced, all upstream dependencies are required to be available in rlib formats. This requirement stems from the reason that a dynamic library cannot be converted into a static format.
    Note that it is impossible to link in native dynamic dependencies to a static library, and in this case warnings will be printed about all unlinked native dynamic dependencies.

In any case, this should not be our case, because it is building an executable.
Relevant points for executables are 3. and 4., but 3. is really about pure Rust dependencies, and the only two things relevant are:

A major goal of the compiler is to ensure that a library never appears more than once in any artifact. For example, if dynamic libraries B and C were each statically linked to library A, then a crate could not link to B and C together because there would be two copies of A.

For most situations, having all libraries available as a dylib is recommended if dynamically linking. For other situations, the compiler will emit a warning if it is unable to determine which formats to link each library with.

They are both about possible failures and warnings, but mostly about Rust dependencies. However, I need to read the error messages first.

@alecandido
Copy link
Member

Just to make some experience, I tried once all the possible installations:

  1. I first tried to build without installing fastNLO: it failed (of course), but with a sensible error message:

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', pineappl_cli/build.rs:30:14
    

    (sensible only reading pineappl_cli/build.rs:30:14, but I could understand)
    I know it's intuitive, but just in case, I would replace that unwrap with an expect("fastNLO library not found, install it please") or something like

  2. then I installed fastNLO and retried: it worked, but with tons of warnings about:

    • unused parameters in header files of fastNLO (a bit stupid, they are headers after all)
    • unused functions in pineappl_cli/src/import.rs (I believe this is work in progress, the moment it will be a proper library it will stop to complain)

    I wonder if it's possible to suppress the first kind of warnings immediately, they are not our fault nor our concern (I'd prefer to have only useful warnings, ones I can act on)

  3. then I compiled with your patch above (i.e. attempting to link dynamically) and it gave me a gigantic error; essentially, it is a gigantic call to the cc compiler with a lot of files, plus a reasonably small error message:

    = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified                                                                                                                                                                                                
    = note: use the `-l` flag to specify native libraries to link                                                                                                                                                                                                                                                                 
    = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)                                                                                                                            
    

    it looks like we're not telling the linker where to look for the dylib (i.e. the .so file), since the build is attempting to make an executable it's reasonable that it has also to link.
    It seems to me that fnlo-tk-config --ldflags is not called anywhere, the result would be

    -L/home/alessandro/.local/lib -lfastnlotoolkit
    

    for my user, as it's intuitive.
    I still don't if we should pass them here:
    https://github.com/N3PDF/pineappl/blob/43298dc3338de29015d02852ea2ce92e835571f7/pineappl_cli/build.rs#L5
    or somewhere else, but I'd expect them to be useful...

@alecandido
Copy link
Member

I was joking: I read about cargo:rustc-flags=FLAGS and I thought it was something different, but it seems it's just a shorthand for cargo:rustc-link-lib=[KIND=]NAME and cargo:rustc-link-search=[KIND=]PATH, that you were already passing.

I tried as well, and I'm trying to specify the KIND, but all the combination attempted (dylib or not in link-lib, native or not in link-search) did not work.

The error message is still coming from the linker, and it's always the same, I report just the end:

          [...]
          /usr/bin/ld: /media/alessandro/moneybin/Projects/N3PDF/pineappl/pineappl_cli/src/import/fastnlo.cpp:658: undefined reference to `fastNLOLHAPDF::~fastNLOLHAPDF()'
          collect2: error: ld returned 1 exit status
                                                                                
  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

so it seems like the flags are not arriving till there, so I'd keep try in this direction.

No progress to report.

@alecandido
Copy link
Member

P.S.: the infinite call to the compiler starts with "cc" "-m64", and it also contains "-lfastnlotoolkit" and "-L" "/home/alessandro/.local/lib" (together with all the dozens of pineappl related flags)

So in principle the flags I believe to be needed are there, thus there is something wrong with them.
At this point, I believe I need a tiny fastNLO program to run the compilation with dynamic linking manually, and iterate on a cleaner thing. I'll try a few more iterations, but if you have a suggestion for such a C++ program, you'll save me quite some time of fastNLO exploration (unless I find the bug before, which seems unlikely).

@cschwan
Copy link
Contributor Author

cschwan commented Feb 20, 2022

  1. I know it's intuitive, but just in case, I would replace that unwrap with an expect("fastNLO library not found, install it please") or something like

Done in commit 15a91fe.

@alecandido
Copy link
Member

This is correctly linking:

#include <fastnlotk/fastNLOLHAPDF.h>

using namespace std;

int main()
{
    auto file = fastNLOLHAPDF("h1.tab", "CT10");

    return 0;
}

with just

g++ -g -Wall -o exp main.cpp $(fnlo-tk-config --ldflags)
# where the last expand to "-L/home/alessandro/.local/lib -lfastnlotoolkit"

Indeed:

❯ ldd exp
        linux-vdso.so.1 (0x00007ffd2c7b1000)
        libfastnlotoolkit.so.0 => /home/alessandro/.local/lib/libfastnlotoolkit.so.0 (0x00007fdb294d5000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fdb292a2000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdb29288000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdb29060000)
        libLHAPDF.so => /home/alessandro/.local/lib/libLHAPDF.so (0x00007fdb28f6b000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fdb28f4f000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdb28e69000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fdb2965a000)

@cschwan
Copy link
Contributor Author

cschwan commented Feb 20, 2022

Concerning the linking error I'm afraid there's a problem with ordering: https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc. I think for the time being we can ignore the error, and hopefully the situation will improve when the fastNLO bridge will be in a separate crate.

@alecandido
Copy link
Member

I see.

The lengthy (but helpful) SO answer taught me something, but now I start to believe that my limited C++ experience is going to kill me, so I'll give up for the time being (we can really investigate anew the moment we have a separate crate).

Nevertheless, there is something mysterious going on in Cargo build, or in cxx. Since the problem is about not finding -lfastnlotoolkit at the correct time, it should be alleviated (if anything), and not enhanced, by linking dynamically. Or, most likely, it should be irrelevant: fastnlotoolkit spelled out its own dependencies when compiled, so they are not a concern, and now it should come in the same place of the static library.
Then, why isn't it working?

Another, more important, thing that I learned once more is that Cargo (in pure Rust) is much better than C/C++ builds, and it's really making my life easier...

@cschwan
Copy link
Contributor Author

cschwan commented Feb 20, 2022

I see.

The lengthy (but helpful) SO answer taught me something, but now I start to believe that my limited C++ experience is going to kill me, so I'll give up for the time being (we can really investigate anew the moment we have a separate crate).

Nevertheless, there is something mysterious going on in Cargo build, or in cxx. Since the problem is about not finding -lfastnlotoolkit at the correct time, it should be alleviated (if anything), and not enhanced, by linking dynamically. Or, most likely, it should be irrelevant: fastnlotoolkit spelled out its own dependencies when compiled, so they are not a concern, and now it should come in the same place of the static library. Then, why isn't it working?

I could be wrong and there's an entirely different reason.

Another, more important, thing that I learned once more is that Cargo (in pure Rust) is much better than C/C++ builds, and it's really making my life easier...

Absolutely, although meson more or less solved C++ builds for me. If you run the fastNLO example and finally compile with ninja -v you should see something like:

[2/2] c++  -o fnlo2pine fnlo2pine.p/fnlo2pine.cpp.o -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -L/home/cschwan/prefix/lib -Wl,--start-group -lfastnlotoolkit /home/cschwan/prefix/lib/libLHAPDF.so /home/cschwan/prefix/lib/libpineappl_capi.so -Wl,--end-group

It uses -Wl,--start-group and Wl,--end-group to enclose its dependencies and apparently the linker then automatically figures out the correct way to link all dependencies.

@alecandido
Copy link
Member

alecandido commented Feb 20, 2022

Absolutely, although meson more or less solved C++ builds for me.

I never tried enough Meson, since I learned Rust it's hard for me to desire going "back" to C++. But it might happen that sooner or later I'll have to do it, and C++ is still better than Fortran (for general purpose programming, for linear algebra I actually like Fortran), and then I'll follow the advice and go with Meson (autotools are bloated and tiresome, and since my master thesis I've started hating CMake, it's not simple and it's poorly documented).

Actually, some more info about are beloved build: I wanted to compare the size of the statically linked binary (libfastnlotoolkit.a is 52 MB, I don't know how much LTO can do, but it's going for sure to increase pineappl binary: better to measure than to attempt a prediction).

This is the result for the size of the pineappl binary:

  • debug profile, no fastnlo (target/debug/pineappl): 56 MB
  • debug profile, fastnlo (target/debug/pineappl): 79 MB
  • release profile, no fastnlo (target/release/pineappl): 3.7 MB
  • release profile, fastnlo: n/a

Actually, I've not been to compile in release mode the statically linked executable. Interestingly, in this case the problem is not linking fastnlotoolkit to pineappl_cli, but instead linking pineappl_capi to fastnlotoolkit.
You can try by yourself running on the current status of the repository the following command:

cargo build --release --features=fastnlo

(swapping the two arguments of cargo makes no difference, fortunately)

@cschwan
Copy link
Contributor Author

cschwan commented Feb 20, 2022

This is the result for the size of the pineappl binary:

* debug profile, no fastnlo (`target/debug/pineappl`): 56 MB

* debug profile, fastnlo (`target/debug/pineappl`): 79 MB

* release profile, no fastnlo (`target/release/pineappl`): 3.7 MB

* release profile, fastnlo: n/a

I can confirm these numbers and interestingly the installed pineappl binary without fastNLO is even smaller with 2.1 MB. I wonder how the 1.6 MB get shaved off.

Actually, I've not been to compile in release mode the statically linked executable. Interestingly, in this case the problem is not linking fastnlotoolkit to pineappl_cli, but instead linking pineappl_capi to fastnlotoolkit. You can try by yourself running on the current status of the repository the following command:

cargo build --release --features=fastnlo

(swapping the two arguments of cargo makes no difference, fortunately)

I can confirm this. But that's just another sign that linking is broken, and it isn't necessarily tied to fastNLO.

@alecandido
Copy link
Member

I can confirm these numbers and interestingly the installed pineappl binary without fastNLO is even smaller with 2.1 MB. I wonder how the 1.6 MB get shaved off.

I don't know what it is exactly doing, but I can tell you that if you run:

strip pineappl

on the 3.7 MB executable, it becomes 1.9 MB. So I guess something similar...

@cschwan
Copy link
Contributor Author

cschwan commented Mar 1, 2022

It seems that with Rust 1.59.0 I can link against the dynamic library, strange ...

cschwan added 5 commits March 12, 2022 09:56
No idea why one has to transpose the indices, something isn't properly
understood
This is now part of `pineappl import ...`
@cschwan
Copy link
Contributor Author

cschwan commented Mar 12, 2022

In commit c43977a I added the changes that we require for https://github.com/NNPDF/fktables/issues/27, and since commit 059491d the conversion should work properly.

@alecandido could you please test this on dom? I can't access it right now. You need to install fastNLO as explained above and then install the CLI as follows:

cargo install --features=fastnlo --path pineappl_cli

You should then be able to run

find /path/to/applgrid/repo -name '*.tab' -exec pineappl import {} {}.pineappl.lz4 NNPDF40_nnlo_as_01180

to convert the fastNLO tables into PineAPPL grids; they will be placed in the same directory next to them in the applgrids repository. If you run

pineappl obl --bins CMS_2JET_7TEV.tab.pineappl.lz4

you should see 1 in the norm column. You can double-check the convolution, but if the normalization is set to 1 I'm quite sure that it will work. Copy the newly converted grids over the wrong ones and you should be able to restart evolving them!

@alecandido
Copy link
Member

@cschwan I would have done, but unfortunately I'm not able to access as well.
I even tried with the INFN VPN, to see if it was a problem related to the actual network you're coming from, but nothing.

Maybe dom is just down...

@cschwan cschwan mentioned this pull request Mar 14, 2022
@cschwan
Copy link
Contributor Author

cschwan commented Mar 15, 2022

There are more fastNLO tables in the official source tarball, and most of the grids work just fine. However, the following abort with 'could not access coefficient table':

  • NJets_nlo-2jet_0101.pineappl.lz4
  • NJets_nlo-2jet_0100.pineappl.lz4
  • NJets_nlo-2jet_0102.pineappl.lz4

My guess is that instead of having interpolation tables some orders are K-factors.

Furthermore, there's a table 'NJetEvents_norm_1-12.pineappl.lz4' for which the bin results are wrong by a factor 500:

b    PineAPPL     fastNLO     rel. diff
--+------------+------------+-----------
0  1.4479542e-5 7.2397708e-3 4.9900000e2
1  1.2100194e-5 6.0500968e-3 4.9900000e2
2  1.1870701e-5 5.9353507e-3 4.9900000e2
3  1.1986148e-5 5.9930739e-3 4.9900000e2
4  1.2132772e-5 6.0663858e-3 4.9900000e2
5  1.2340099e-5 6.1700495e-3 4.9900000e2
6  1.2480707e-5 6.2403537e-3 4.9900000e2
7  1.2630516e-5 6.3152581e-3 4.9900000e2
8  1.2806140e-5 6.4030702e-3 4.9900000e2
9  6.4738462e-6 6.4738462e-3 9.9900000e2
10 6.6040672e-6 6.6040672e-3 9.9900000e2
11 6.6632940e-6 6.6632940e-3 9.9900000e2

@alecandido
Copy link
Member

alecandido commented Mar 15, 2022

My guess is that instead of having interpolation tables some orders are K-factors.

Unfortunately there is no actual documentation of fastNLO: there are the papers, but they do not document the code itself.
Do you know/believe that there is a dedicated structure for K-factors?

Furthermore, there's a table 'NJetEvents_norm_1-12.pineappl.lz4' for which the bin results are wrong by a factor 500/1000:

This is really a weirdly regular factor, I guess there should be a reasonable explanation. Something like bins' width again?

@cschwan
Copy link
Contributor Author

cschwan commented Mar 16, 2022

Unfortunately there is no actual documentation of fastNLO: there are the papers, but they do not document the code itself.
Do you know/believe that there is a dedicated structure for K-factors?

You can run doxygen over the source code. But I'm reading the source code (the headers mostly) itself, as the documentation is often vague or even wrong in small instances.

@cschwan
Copy link
Contributor Author

cschwan commented Mar 16, 2022

This is really a weirdly regular factor, I guess there should be a reasonable explanation. Something like bins' width again?

This is very likely. As this isn't a important right now I've opened a new Issue for it, NNPDF/pinecards#126.

I'd like to merge this PR now, as everything that was working is working with the new converter. Do you agree or do you think there's something missing? You requested a Python API for the conversion, but for that I'll probably open a separate Issue or I'll add it into master directly.

@alecandido
Copy link
Member

I perfectly agree on decoupling things: the goal of this PR is written in the name, and it's only about the CLI. As you said, it's definitely not worse than before, and now a proper part of the CLI.

Let me try to compile it one last time, and I'll go quickly through the changes to see if everything looks alright. In any case, if I'll find something that is not strictly needed, I'll just open another issue, I'd like to merge as well.

@cschwan
Copy link
Contributor Author

cschwan commented Mar 16, 2022

Thanks, let me know if it works, @alecandido!

Copy link
Member

@alecandido alecandido left a comment

Choose a reason for hiding this comment

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

Everything's fine, just a couple of comments.

@cschwan cschwan merged commit 4119b90 into master Mar 16, 2022
@cschwan cschwan deleted the import-fastnlo branch March 16, 2022 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants