NEURON
mem_layout_util.cpp
Go to the documentation of this file.
1 /*
2 # =============================================================================
3 # Copyright (c) 2016 - 2021 Blue Brain Project/EPFL
4 #
5 # See top-level LICENSE file for details.
6 # =============================================================================
7 */
8 
9 #include "mem_layout_util.hpp"
10 
11 #include <numeric>
12 
13 namespace coreneuron {
14 
15 /// calculate size after padding for specific memory layout
16 // Warning: this function is declared extern in nrniv_decl.h
17 int nrn_soa_padded_size(int cnt, int layout) {
18  return soa_padded_size<NRN_SOA_PAD>(cnt, layout);
19 }
20 
21 /// return the new offset considering the byte aligment settings
22 size_t nrn_soa_byte_align(size_t size) {
23  static_assert(NRN_SOA_BYTE_ALIGN % sizeof(double) == 0,
24  "NRN_SOA_BYTE_ALIGN should be a multiple of sizeof(double)");
25  constexpr size_t dbl_align = NRN_SOA_BYTE_ALIGN / sizeof(double);
26  size_t remainder = size % dbl_align;
27  if (remainder) {
28  size += dbl_align - remainder;
29  }
30  nrn_assert((size * sizeof(double)) % NRN_SOA_BYTE_ALIGN == 0);
31  return size;
32 }
33 
34 int nrn_i_layout(int icnt, int cnt, int isz, int sz, int layout) {
35  switch (layout) {
36  case Layout::AoS:
37  return icnt * sz + isz;
38  case Layout::SoA:
39  int padded_cnt = nrn_soa_padded_size(cnt, layout);
40  return icnt + isz * padded_cnt;
41  }
42 
43  nrn_assert(false);
44  return 0;
45 }
46 
47 std::array<int, 3> legacy2soaos_index(int legacy_index, const std::vector<int>& array_dims) {
48  int variable_count = static_cast<int>(array_dims.size());
49  int row_width = std::accumulate(array_dims.begin(), array_dims.end(), 0);
50 
51  int column_index = legacy_index % row_width;
52 
53  int instance_index = legacy_index / row_width;
54  int variable_index = 0;
55  int prefix_sum = 0;
56  for (size_t k = 0; k < variable_count - 1; ++k) {
57  if (column_index >= prefix_sum + array_dims[k]) {
58  prefix_sum += array_dims[k];
59  variable_index = k + 1;
60  } else {
61  break;
62  }
63  }
64  int array_index = column_index - prefix_sum;
65 
66  return {instance_index, variable_index, array_index};
67 }
68 
69 int soaos2cnrn_index(const std::array<int, 3>& soaos_indices,
70  const std::vector<int>& array_dims,
71  int padded_node_count,
72  int* permute) {
73  auto [i, j, k] = soaos_indices;
74  if (permute) {
75  i = permute[i];
76  }
77 
78  int offset = 0;
79  for (int ij = 0; ij < j; ++ij) {
80  offset += padded_node_count * array_dims[ij];
81  }
82 
83  int K = array_dims[j];
84  return offset + i * K + k;
85 }
86 
87 
88 } // namespace coreneuron
Definition: utility.h:81
#define cnt
Definition: tqueue.hpp:44
#define i
Definition: md1redef.h:19
static RNG::key_type k
Definition: nrnran123.cpp:9
#define NRN_SOA_BYTE_ALIGN
Definition: memory.h:26
THIS FILE IS AUTO GENERATED DONT MODIFY IT.
int soaos2cnrn_index(const std::array< int, 3 > &soaos_indices, const std::vector< int > &array_dims, int padded_node_count, int *permute)
Compute the CoreNEURON index given an SoAoS index.
int nrn_i_layout(int icnt, int cnt, int isz, int sz, int layout)
This function return the index in a flat array of a matrix coordinate (icnt, isz).
std::array< int, 3 > legacy2soaos_index(int legacy_index, const std::vector< int > &array_dims)
Split a legacy index into the three SoAoS indices.
size_t nrn_soa_byte_align(size_t size)
return the new offset considering the byte aligment settings
int nrn_soa_padded_size(int cnt, int layout)
calculate size after padding for specific memory layout
static int permute(int i, NrnThread &nt)
Definition: prcellstate.cpp:28
#define nrn_assert(x)
assert()-like macro, independent of NDEBUG status
Definition: nrn_assert.h:33
size_t j