Skip to content

Commit be81384

Browse files
Pass the computation of a Operator slice as a callback
1 parent eec6705 commit be81384

3 files changed

Lines changed: 102 additions & 83 deletions

File tree

examples/cpp/evolve-grid-identity.cpp

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,36 @@ std::vector<std::size_t> unravel_index(std::size_t flat_index, const std::vector
2424
return coords;
2525
}
2626

27-
std::vector<double> generate_fake_ekos(
28-
std::vector<int> pids_in,
29-
std::vector<double> x_in,
30-
std::vector<int> pids_out,
31-
std::vector<double> x_out
27+
extern "C" void generate_fake_ekos(
28+
const int* pids_in,
29+
const double* x_in,
30+
const int* pids_out,
31+
const double* x_out,
32+
double* eko_buffer,
33+
pineappl_conv_type conv_type,
34+
std::size_t pids_in_len,
35+
std::size_t x_in_len,
36+
std::size_t pids_out_len,
37+
std::size_t x_out_len
3238
) {
33-
std::size_t flat_len = x_out.size() * x_in.size() * pids_out.size() * pids_in.size();
34-
std::vector<double> ops(flat_len);
35-
39+
// Ignore unused variables
40+
(void)pids_in;
41+
(void)x_in;
42+
(void)pids_out;
43+
(void)x_out;
44+
(void) conv_type;
45+
46+
std::size_t flat_len = pids_in_len * x_in_len * pids_out_len * x_out_len;
3647
// NOTE: The EKO has to have as shape: (pids_in, x_in, pids_out, x_out)
37-
std::vector<std::size_t> shape = {pids_in.size(), x_in.size(), pids_out.size(), x_out.size()};
48+
std::vector<std::size_t> shape = {pids_in_len, x_in_len, pids_out_len, x_out_len};
3849
for (std::size_t i = 0; i != flat_len; i++) {
3950
std::vector<std::size_t> coords = unravel_index(i, shape);
4051

4152
double delta_ik = (coords[0] == coords[2]) ? 1.0 : 0.0;
4253
double delta_jl = (coords[1] == coords[3]) ? 1.0 : 0.0;
4354

44-
ops[i] = delta_ik * delta_jl;
55+
eko_buffer[i] = delta_ik * delta_jl;
4556
}
46-
47-
return ops;
4857
}
4958

5059
void print_results(std::vector<double> dxsec_grid, std::vector<double> dxsec_fktable) {
@@ -152,18 +161,6 @@ int main() {
152161
// std::vector<int> pids_out = {-6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 21, 22};
153162
std::vector<int> pids_out = pids_in;
154163

155-
// The Evolution Operator is a vector with length `N_conv * N_Q2_slices * Σ product(OP shape)`
156-
std::vector<double> op_slices;
157-
std::size_t flat_len = x_in.size() * x_in.size() * pids_in.size() * pids_out.size();
158-
for (std::size_t _i = 0; _i != conv_types.size(); _i++) {
159-
for (std::size_t j = 0; j != fac1.size(); j++) {
160-
std::vector<double> eko = generate_fake_ekos(pids_in, x_in, pids_out, x_in);
161-
for (std::size_t k = 0; k != flat_len; k++) {
162-
op_slices.push_back(eko[k]);
163-
}
164-
}
165-
}
166-
167164
// Construct the values of alphas table
168165
std::vector<double> alphas_table;
169166
for (double q2 : ren1) {
@@ -189,7 +186,7 @@ int main() {
189186
// - `ren1`: values of the renormalization scales
190187
// - `alphas_table`: values of alphas for each renormalization scales
191188
pineappl_fk_table* fktable = pineappl_grid_evolve(grid, opinfo_slices.data(),
192-
max_orders.data(), op_slices.data(), x_in.data(),
189+
max_orders.data(), generate_fake_ekos, x_in.data(),
193190
x_in.data(), pids_in.data(), pids_out.data(),
194191
tensor_shape.data(), xi.data(), ren1.data(), alphas_table.data());
195192

examples/cpp/evolve-grid.cpp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,36 @@ std::vector<std::size_t> unravel_index(std::size_t flat_index, const std::vector
8282
return coords;
8383
}
8484

85-
std::vector<double> generate_fake_ekos(std::string filename) {
86-
std::ifstream input_file(filename);
87-
std::vector<double> ops;
85+
extern "C" void generate_fake_ekos(
86+
const int* pids_in,
87+
const double* x_in,
88+
const int* pids_out,
89+
const double* x_out,
90+
double* eko_buffer,
91+
pineappl_conv_type conv_type,
92+
std::size_t pids_in_len,
93+
std::size_t x_in_len,
94+
std::size_t pids_out_len,
95+
std::size_t x_out_len
96+
) {
97+
// Ignore unused variables
98+
(void)pids_in;
99+
(void)x_in;
100+
(void)pids_out;
101+
(void)x_out;
102+
(void) conv_type;
103+
(void)pids_in_len;
104+
(void)x_in_len;
105+
(void)pids_out_len;
106+
(void)x_out_len;
107+
108+
std::ifstream input_file("../../test-data/EKO_LHCB_WP_7TEV.txt");
88109
double weight_value;
89110

111+
std::size_t count = 0;
90112
while (input_file >> weight_value) {
91-
ops.push_back(weight_value);
113+
eko_buffer[count++] = weight_value;
92114
}
93-
94-
return ops;
95115
}
96116

97117
void print_results(std::vector<double> dxsec_grid, std::vector<double> dxsec_fktable) {
@@ -126,7 +146,6 @@ void print_results(std::vector<double> dxsec_grid, std::vector<double> dxsec_fkt
126146
int main() {
127147
// TODO: How to get a Grid that can be evolved??
128148
std::string filename = "../../test-data/LHCB_WP_7TEV_opt.pineappl.lz4";
129-
std::string ekoname = "../../test-data/EKO_LHCB_WP_7TEV.txt";
130149

131150
// disable LHAPDF banners to guarantee deterministic output
132151
LHAPDF::setVerbosity(0);
@@ -200,18 +219,6 @@ int main() {
200219
std::vector<int> pids_in = PIDS;
201220
std::vector<int> pids_out = PIDS;
202221

203-
// The Evolution Operator is a vector with length `N_conv * N_Q2_slices * Σ product(OP shape)`
204-
std::vector<double> op_slices;
205-
std::size_t flat_len = XGRID.size() * XGRID.size() * pids_in.size() * pids_out.size();
206-
for (std::size_t _i = 0; _i != conv_types.size(); _i++) {
207-
for (std::size_t j = 0; j != fac1.size(); j++) {
208-
std::vector<double> eko = generate_fake_ekos(ekoname);
209-
for (std::size_t k = 0; k != flat_len; k++) {
210-
op_slices.push_back(eko[k]);
211-
}
212-
}
213-
}
214-
215222
// Construct the values of alphas table
216223
std::vector<double> alphas_table;
217224
for (double q2 : ren1) {
@@ -237,7 +244,7 @@ int main() {
237244
// - `ren1`: values of the renormalization scales
238245
// - `alphas_table`: values of alphas for each renormalization scales
239246
pineappl_fk_table* fktable = pineappl_grid_evolve(grid, opinfo_slices.data(),
240-
max_orders.data(), op_slices.data(), XGRID.data(),
247+
max_orders.data(), generate_fake_ekos, XGRID.data(),
241248
XGRID.data(), pids_in.data(), pids_out.data(),
242249
tensor_shape.data(), xi.data(), ren1.data(), alphas_table.data());
243250

pineappl_capi/src/lib.rs

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,9 +2132,20 @@ pub unsafe extern "C" fn pineappl_grid_evolve_info(
21322132
#[no_mangle]
21332133
pub unsafe extern "C" fn pineappl_grid_evolve(
21342134
grid: *mut Grid,
2135-
op_info: *mut OperatorInfo,
2135+
operator_infos: *mut OperatorInfo,
21362136
max_orders: *const u8,
2137-
operators: *mut f64,
2137+
operators: extern "C" fn(
2138+
*const i32,
2139+
*const f64,
2140+
*const i32,
2141+
*const f64,
2142+
*mut f64,
2143+
ConvType,
2144+
usize,
2145+
usize,
2146+
usize,
2147+
usize,
2148+
),
21382149
x_in: *const f64,
21392150
x_out: *const f64,
21402151
pids_in: *const i32,
@@ -2167,46 +2178,50 @@ pub unsafe extern "C" fn pineappl_grid_evolve(
21672178
.map(pineappl::convolutions::Conv::conv_type)
21682179
.collect();
21692180

2170-
let op_info = unsafe {
2171-
slice::from_raw_parts(op_info, conv_types.len() * evolve_info.fac1.len())
2181+
let operator_infos = unsafe {
2182+
slice::from_raw_parts(operator_infos, conv_types.len() * evolve_info.fac1.len())
21722183
.chunks_exact(evolve_info.fac1.len())
21732184
};
2174-
21752185
let total_shape: usize = eko_shape.iter().product();
2176-
let operators = unsafe {
2177-
slice::from_raw_parts(
2178-
operators,
2179-
conv_types.len() * evolve_info.fac1.len() * total_shape,
2180-
)
2181-
.chunks_exact(evolve_info.fac1.len() * total_shape)
2182-
};
21832186

2184-
let slices = op_info
2185-
.zip(operators)
2186-
.map(|(op_infos, op_vals)| {
2187-
op_infos
2188-
.iter()
2189-
.zip(op_vals.chunks_exact(total_shape))
2190-
.map(|(op_info, values)| {
2191-
let operator_slice_info = OperatorSliceInfo {
2192-
pid_basis: op_info.pid_basis,
2193-
fac0: op_info.fac0,
2194-
pids0: pids_out.to_vec(),
2195-
x0: x_out.to_vec(),
2196-
fac1: op_info.fac1,
2197-
pids1: pids_in.to_vec(),
2198-
x1: x_in.to_vec(),
2199-
conv_type: op_info.conv_type,
2200-
};
2201-
2202-
let array = Array4::from_shape_vec(
2203-
Ix4(eko_shape[0], eko_shape[1], eko_shape[2], eko_shape[3]),
2204-
values.to_vec(),
2205-
)
2206-
.unwrap();
2207-
2208-
Ok::<_, std::io::Error>((operator_slice_info, CowArray::from(array)))
2209-
})
2187+
let slices = operator_infos
2188+
.map(|op_infos| {
2189+
op_infos.iter().map(|op_info| {
2190+
let operator_slice_info = OperatorSliceInfo {
2191+
pid_basis: op_info.pid_basis,
2192+
fac0: op_info.fac0,
2193+
pids0: pids_out.to_vec(),
2194+
x0: x_out.to_vec(),
2195+
fac1: op_info.fac1,
2196+
pids1: pids_in.to_vec(),
2197+
x1: x_in.to_vec(),
2198+
conv_type: op_info.conv_type,
2199+
};
2200+
2201+
// Let Rust manages the memory by allocating a flat vector of zeros as a placeholder
2202+
// to hold the evolution operator data.
2203+
let mut eko_slice = vec![0.0; total_shape];
2204+
operators(
2205+
pids_in.as_ptr(),
2206+
x_in.as_ptr(),
2207+
pids_out.as_ptr(),
2208+
x_out.as_ptr(),
2209+
eko_slice.as_mut_ptr(),
2210+
op_info.conv_type,
2211+
pids_in.len(),
2212+
x_in.len(),
2213+
pids_out.len(),
2214+
x_out.len(),
2215+
);
2216+
2217+
let array = Array4::from_shape_vec(
2218+
Ix4(eko_shape[0], eko_shape[1], eko_shape[2], eko_shape[3]),
2219+
eko_slice,
2220+
)
2221+
.unwrap();
2222+
2223+
Ok::<_, std::io::Error>((operator_slice_info, CowArray::from(array)))
2224+
})
22102225
})
22112226
.collect();
22122227

0 commit comments

Comments
 (0)