Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
types of convolution functions, so we simply convert the grid to use only
proton PDFs

### Changed

- the function `Grid::evolve` now makes use of parallelization to take advantage
of the number of CPU cores available using the Rayon crate; the number of CPU
cores to be used can be controlled via the `RAYON_NUM_THREADS` environment
variable

## [1.1.0] - 08/07/2025

### Added
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pineappl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ itertools = "0.10.1"
lz4_flex = "0.9.2"
ndarray = { features = ["serde"], version = "0.15.4" }
pineappl-v0 = { package = "pineappl", version = "0.8.2" }
rayon = "1.5.1"
rustc-hash = "1.1.0"
serde = { features = ["derive"], version = "1.0.130" }
thiserror = "1.0.30"
Expand Down
50 changes: 25 additions & 25 deletions pineappl/src/evolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use ndarray::{
s, Array1, Array2, Array3, ArrayD, ArrayView1, ArrayView4, ArrayViewD, ArrayViewMutD, Axis,
Ix1, Ix2,
};
use rayon::iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
use std::iter;

/// This structure captures the information needed to create an evolution kernel operator (EKO) for
Expand Down Expand Up @@ -400,8 +401,6 @@ pub(crate) fn evolve_slice(
let channels0 = channels0;

let mut sub_fk_tables = Vec::with_capacity(grid.bwfl().len() * channels0.len());

// TODO: generalize to `n`
let mut last_x1 = vec![Vec::new(); infos.len()];
let mut eko_slices = vec![Vec::new(); infos.len()];
let dim: Vec<_> = infos.iter().map(|info| info.x0.len()).collect();
Expand Down Expand Up @@ -445,34 +444,35 @@ pub(crate) fn evolve_slice(
}
}

for (pids1, factor) in channel1.entry() {
// find the tuple of EKOs that evolve the current channel entry of the grid into
// every channel of the FK-table
let tmp = channels0.iter().map(|pids0| {
izip!(pids0, pids1, &pids01, &eko_slices)
.map(|(&pid0, &pid1, pids, slices)| {
// for each convolution ...
pids.iter().zip(slices).find_map(|(&(p0, p1), op)| {
// find the EKO that matches both the FK-table and the grid PID
((p0 == pid0) && (p1 == pid1)).then_some(op)
// for each channel in the FK-table ...
tables
.par_iter_mut()
.zip(&channels0)
.for_each(|(fk_table, pids0)| {
// and each sub-channel in the grid ...
for (pids1, factor) in channel1.entry() {
// find the tuple of EKOs that evolve this combination
let ops: Option<Box<[_]>> = izip!(pids0, pids1, &pids01, &eko_slices)
.map(|(&pid0, &pid1, pids, slices)| {
// for each convolution ...
pids.iter().zip(slices).find_map(|(pid01, op)| {
// find the EKO that matches both the FK-table and the grid PID
(pid01 == &(pid0, pid1)).then_some(op)
})
})
})
// if an EKO isn't found, it's zero and therefore the whole FK-table
// channel contribution will be zero
.collect::<Option<Box<[_]>>>()
});

for (fk_table, ops) in tables.iter_mut().zip(tmp) {
// if there's one zero EKO, the entire tuple is `None`
if let Some(ops) = ops {
general_tensor_mul(*factor, array.view(), &ops, fk_table.view_mut());
// if an EKO isn't found, it's zero and therefore the whole FK-table
// channel contribution will be zero
.collect();

// if there's one zero EKO, the entire tuple is `None`
if let Some(ops) = ops {
general_tensor_mul(*factor, array.view(), &ops, fk_table.view_mut());
}
}
}
}
});
}

let mut node_values = vec![scale_values.to_vec()];

for info in infos {
node_values.push(info.x0.clone());
}
Expand Down