0

I am currently working on a big project involving repast_hpc and mpi. I wanted to implement a two dimensional shared (across processes) array, because repast_hpc itself does not seem to come with that. For that I need an array member of a class. However I do not know the size of the array at compile time. I need to be able to access and change the values in constant time. The code given below is my current header file, where the problem is located. How can I get a array member like the values in array in c++11?

template <typename Value>
class SharedValueField {
    private:
        Value[][] values;
        std::queue<ValueChangePackage<Value>> changes;
    public:
        void initializeValueChange(int x, int y, Value value);
        Value getValue(int x, int y);
        void update();
};

All help appreciated. Thanks! Tritos

I already tried using std::array. That has the same problems. I cant use std::vector, because they dont allow for constnt-time random element value manipulation.

Tritos
  • 1
  • 1
  • 2
    C++ doesn't have flexible arrays. In C they need to be _last_ in the `struct` and only the first dimension can be left "blank" – Ted Lyngmo Jan 31 '23 at 14:20
  • Will the size of the array only need to be set once? `std::vector` *does* allow constant time random element manipulation. It is really just a contiguous block of memory under the hood, after all. – AndyG Jan 31 '23 at 14:20
  • 3
    What do you mean with `I cant use std::vector, because they dont allow for constnt-time random element value manipulation.`? `a[5] = 7;` takes for `std::vector` as long as for `std::array` or C style arrays. – mch Jan 31 '23 at 14:20
  • if you don't know the size then its not an array – 463035818_is_not_an_ai Jan 31 '23 at 14:22
  • 3
    While it's possible to share an array across processes with MPI, it's a bit like teaching a dog to walk on two legs, amusing but rather misses the point. In MPI it's much more common to partition an array across processes, and to share as little as possible. Why do you want to implement a shared array? – High Performance Mark Jan 31 '23 at 14:26
  • I'm with @HighPerformanceMark : sharing data over processes is not in the nature of MPI. Unless every process really needs fast access to *every single* element of the data, you should distribute your data, and communicate elements as needed. That's dictated by your algorithm. – Victor Eijkhout Jan 31 '23 at 14:51
  • @463035818_is_not_a_number I know the size at runtime. – Tritos Jan 31 '23 at 15:04
  • @HighPerformanceMark I am writing a pheromone map for an agent-simulation. The „map“ is divided into cells and each process controls a block of the map and the agents within. For the pheromone system to work correctly, all processes need to know the values within their block and of the other processes next to them. So the data is already distributed but i will always have to share the values on the edges. That is what im trying to achieve. – Tritos Jan 31 '23 at 15:05
  • 1
    `std::vector` supports random access in O(1) (i.e. constant time), and does not require the size to be known at compile time. I don't see any disadvantage with `std::vector` in compare to old C style arrays. And you you can just use a strided 1D `std::vector`, and access element with a simple formula: `y * stride + x`. – wohlstad Jan 31 '23 at 15:11
  • 1
    What OP describes in their comment is not, I don't think, what I would call a *shared* array. It seems OP means something much more like a standard domain decomposition where each process has its own (private) chunk of the array and share ghost/halo cells at the boundary which need to be kept consistent. Right in the sweet spot for MPI programs. OP might want to edit the question. – High Performance Mark Jan 31 '23 at 15:12
  • @AndyG I might have misinterpreted the line „ Insertion or removal of elements - linear in the distance to the end of the vector O(n)“ from (https://en.cppreference.com/w/cpp/container/vector). Does this only apply if the length of the vector changes? (It does not in my application) – Tritos Jan 31 '23 at 15:13
  • "Insertion or removal" implies that the size changes – 463035818_is_not_an_ai Jan 31 '23 at 15:15
  • @Tritos it's only relevant if you e.g. want to remove an element. Since the `std::vector`'s memory must be continous, all the elements after the removed one are copied "backwards". And there could be O(n) such elements. Similarly it's O(n) for insertion. – wohlstad Jan 31 '23 at 15:15
  • @Tritos There are ways around the O(n) cost of adding and removal. For addition, if you know the maximum number of elements beforehand, then you can presize the vector so that reallocation never happens. For removal, if the order of the elements in the vector does not need to remain stable, then you can swap the last element with the element to be removed, then pop the last element off. – AndyG Jan 31 '23 at 15:20

1 Answers1

0

Using ‚std::vector‘ works after all. As explained by many people in the comments, only changing the size of the vector has time-complexity in O(n). I only need to reassign elements, which works fine.

Tritos
  • 1
  • 1