Skip to content

Commit a2d9f87

Browse files
committed
transforming states with transposed matrix is 2,580% faster
1 parent 7a4babb commit a2d9f87

4 files changed

Lines changed: 71 additions & 40 deletions

File tree

benches/bench_transform_states.c

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
#define CUQDYN_CONF "../tests/data/nfkb_cuqdyn_config.xml"
99

1010
void bench_transform_states();
11+
void bench_transform_states_2();
1112

1213
int main()
1314
{
1415
CuqDynContext context = init_cuqdyn_context_from_file(CUQDYN_CONF);
1516
CuqdynConf *conf = get_cuqdyn_conf(context);
1617

1718
BenchFunc funcs[] = {
18-
bench_transform_states
19+
bench_transform_states,
20+
bench_transform_states_2
1921
};
2022

2123
BenchOptions *options = create_bench_options("Transform States", funcs, sizeof(funcs) / sizeof(funcs[0]));
@@ -25,49 +27,43 @@ int main()
2527
return 0;
2628
}
2729

30+
#define STATES_ROWS 1000
31+
#define STATES_COLS 16
32+
2833
void bench_transform_states()
2934
{
30-
#define STATES_ROWS 28
31-
#define STATES_COLS 16
32-
33-
sunrealtype states_values[STATES_COLS][STATES_ROWS] = {
34-
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
35-
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
36-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
37-
3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
38-
4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
39-
5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
40-
6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
41-
7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
42-
8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
43-
9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
44-
10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
45-
11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
46-
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
47-
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
48-
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
49-
3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
50-
4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
51-
5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
52-
6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
53-
7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
54-
8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
55-
9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
56-
10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
57-
11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
58-
};
35+
sunrealtype states_values[STATES_COLS][STATES_ROWS] = { 0 };
5936

6037
SUNMatrix states = NewDenseMatrix(STATES_ROWS, STATES_COLS);
6138

62-
for (int i = 0; i < STATES_ROWS; ++i)
39+
for (int i = 0; i < STATES_ROWS; ++i)
6340
{
64-
for (int j = 0; j < STATES_COLS; ++j)
41+
for (int j = 0; j < STATES_COLS; ++j)
6542
{
66-
SM_ELEMENT_D(states, i, j) = states_values[j][i];
43+
SM_ELEMENT_D(states, i, j) = states_values[j][i];
6744
}
6845
}
6946

7047
SUNMatrix transformed_states = transform_states(states);
7148

7249
SUNMatDestroy(transformed_states);
7350
}
51+
52+
void bench_transform_states_2()
53+
{
54+
sunrealtype states_values[STATES_ROWS][STATES_COLS] = { 0 };
55+
56+
SUNMatrix states = NewDenseMatrix(STATES_COLS, STATES_ROWS);
57+
58+
for (int i = 0; i < STATES_ROWS; ++i)
59+
{
60+
for (int j = 0; j < STATES_COLS; ++j)
61+
{
62+
SM_ELEMENT_D(states, j, i) = states_values[i][j];
63+
}
64+
}
65+
66+
SUNMatrix transformed_states = transform_states_2(states);
67+
68+
SUNMatDestroy(transformed_states);
69+
}

benches/bench_wrapper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ extern "C" void run_benchmark(BenchOptions *options)
4545
PAPI_cleanup_eventset(EventSet);
4646
PAPI_destroy_eventset(&EventSet);
4747

48-
std::cout << "#### Cache analysis for " << options->name << " ###\n"
49-
<< "L1 cache misses: " << values[0] << ", L2 cache misses: " << values[1] << "\n"
50-
<< "L1 cache hits: " << values[2] << ", L2 cache hits: " << values[3] << "\n";
48+
// std::cout << "#### Cache analysis for " << options->name << " ###\n"
49+
// << "L1 cache misses: " << values[0] << ", L2 cache misses: " << values[1] << "\n"
50+
// << "L1 cache hits: " << values[2] << ", L2 cache hits: " << values[3] << "\n";
5151
}
5252

5353
PAPI_shutdown();

modules/cuqdyn-c/include/states_transformer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@
1010
/// transformation expr is defined in the config XML.
1111
SUNMatrix transform_states(SUNMatrix states);
1212

13+
SUNMatrix transform_states_2(SUNMatrix states);
14+
1315
#endif //STATES_TRANSFORMER_H

modules/cuqdyn-c/src/states_transformer.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
// Created by borja on 12/06/25.
33
//
44
#include <nvector/nvector_serial.h>
5+
#include <string.h>
56
#include <sunmatrix/sunmatrix_dense.h>
67

78
#include "config.h"
89
#include "matlab.h"
10+
#include "sundials/sundials_matrix.h"
11+
#include "sundials/sundials_types.h"
912

1013
extern void eval_states_transformer_expr(sunrealtype *input, sunrealtype *output, CuqDynContext context);
1114

@@ -20,10 +23,10 @@ SUNMatrix transform_states(SUNMatrix states)
2023

2124
const int rows = SM_ROWS_D(states);
2225
const int cols = SM_COLUMNS_D(states);
23-
26+
2427
SUNMatrix transformed_result = NewDenseMatrix(rows, conf->states_transformer.count + 1); // + 1 adds the time column
2528
sunrealtype *output = malloc(conf->states_transformer.count * sizeof(sunrealtype));
26-
29+
2730
for (int i = 0; i < rows; ++i)
2831
{
2932
N_Vector input = copy_matrix_row(states, i, 1, cols);
@@ -38,8 +41,38 @@ SUNMatrix transform_states(SUNMatrix states)
3841

3942
N_VDestroy(input);
4043
}
41-
44+
4245
free(output);
4346
SUNMatDestroy(states);
4447
return transformed_result;
45-
}
48+
}
49+
50+
SUNMatrix transform_states_2(SUNMatrix transposed_states)
51+
{
52+
CuqdynConf *conf = get_cuqdyn_conf(get_cuqdyn_context());
53+
54+
if (conf->states_transformer.count == 0)
55+
{
56+
return transposed_states;
57+
}
58+
59+
const int rows = SM_ROWS_D(transposed_states);
60+
const int cols = SM_COLUMNS_D(transposed_states);
61+
62+
SUNMatrix transposed_result = NewDenseMatrix(conf->states_transformer.count + 1, rows);
63+
64+
for (int i = 0; i < rows; ++i)
65+
{
66+
// The first element is the time point
67+
sunrealtype *input = &SM_COLUMN_D(transposed_states, i)[1];
68+
sunrealtype *dest = &SM_COLUMN_D(transposed_result, i)[1];
69+
70+
eval_states_transformer_expr(input, dest, get_cuqdyn_context());
71+
72+
dest[0] = input[0]; // Copy the time point to the first element of the transformed state
73+
}
74+
75+
SUNMatDestroy(transposed_states);
76+
77+
return transposed_result;
78+
}

0 commit comments

Comments
 (0)