Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F90050134
grid.hh
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Oct 28, 20:45
Size
5 KB
Mime Type
text/x-c++
Expires
Wed, Oct 30, 20:45 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
21999349
Attached To
rSCMINICLUSTER SCITAS Mini Cluster
grid.hh
View Options
#ifndef GRID_HH
#define GRID_HH
#include <QDebug>
#include <QMutex>
#include <QQueue>
#include <QMutexLocker>
#include <QSemaphore>
#include <cstddef>
#include <queue>
#include <vector>
enum GridState {
_normal_state,
_randomize,
_clear
};
class GridInfo {
public:
GridInfo() : _origin{0, 0}, _size{0, 0} {}
GridInfo(const int origin[2], const int size[2])
: _origin{origin[0], origin[1]}, _size{size[0], size[1]} {}
GridInfo(const GridInfo & other)
: _origin{other._origin[0], other._origin[1]},
_size{other._size[0], other._size[1]} {}
void setOrigin(const int origin[2]) {
_origin[0] = origin[0];
_origin[1] = origin[1];
}
void setSize(const int size[2]) {
_size[0] = size[0];
_size[1] = size[1];
}
int size(int i) const { return _size[i]; }
int origin(int i) const { return _origin[i]; }
const int * size() const { return _size; }
const int * origin() const { return _origin; }
protected:
int _origin[2];
int _size[2];
};
class SendGrid : public GridInfo {
typedef char T;
public:
SendGrid(const int origin[2], const int size[2])
: GridInfo(origin, size), _data(size[0] * size[1], 0){};
SendGrid(const SendGrid & other) : GridInfo(other), _data(other._data) {}
T & operator()(int i, int j) { return _data[i * _size[1] + j]; }
const T & operator()(int i, int j) const { return _data[i * _size[1] + j]; }
T * data() { return _data.data(); }
private:
std::vector<T> _data;
};
class Grid {
typedef uint32_t T;
public:
Grid(size_t m = 0, size_t n = 0)
: _pieces_sem(0), _nb_pieces(0), _data(n * m), _size{m, n}, _pieces(0),
_queues(0), _state(_normal_state) {
}
~Grid() { }
void resize(size_t m, size_t n) {
_size[0] = m;
_size[1] = n;
_data.resize(n * m);
}
T & operator()(size_t i, size_t j) { return _data[j + i * _size[1]]; }
const T & operator()(size_t i, size_t j) const {
return _data[j + i * _size[1]];
}
size_t getNbPieces() {
QMutexLocker locker(&_nb_pieces_lock);
return _nb_pieces;
}
size_t size(int i) const { return _size[i]; }
void getPiece() { return _pieces_sem.acquire(1); }
void setPiece(size_t nb_pieces) {
QMutexLocker locker(&_nb_pieces_lock);
_nb_pieces = nb_pieces;
_queues.clear();
_queues.resize(nb_pieces);
_pieces.resize(nb_pieces);
_state.resize(nb_pieces);
setState(_normal_state);
}
void releasePieces() { _pieces_sem.release(_nb_pieces); }
void releasePiece() { _pieces_sem.release(1); }
void unconnectPiece(__attribute__((unused)) int prank) {
QMutexLocker locker(&_nb_pieces_lock);
--_nb_pieces;
if (_nb_pieces == 0)
_pieces_sem.acquire(_pieces_sem.available());
}
void dataToSend(const SendGrid & grid) {
class Pred {
public:
Pred(const GridInfo & grid_info) : a(grid_info) {}
bool operator()(const GridInfo & b) {
return a.origin(0) >= b.origin(0) && a.origin(1) >= b.origin(1) &&
a.origin(0) < b.origin(0) + b.size(0) &&
a.origin(1) < b.origin(1) + b.size(1);
}
private:
const GridInfo & a;
};
Pred pred(grid);
auto it = std::find_if(_pieces.begin(), _pieces.end(), pred);
if (it == _pieces.end())
return;
qDebug() << "Click in piece" << (it - _pieces.begin());
bool split[2] = {false, false};
for (int i = 0; i < 2; ++i) {
if (it->origin(i) + it->size(i) < grid.origin(i) + grid.size(i))
split[i] = true;
}
qDebug() << "Need split" << split[0] << split[1];
auto extract_grid = [&grid, &pred, this](const int * origin,
const int * size) -> void {
qDebug() << "Extracting grid" << origin[0] << origin[1] << "--" << size[0]
<< size[1];
int offset[2] = {origin[0] - grid.origin(0), origin[1] - grid.origin(1)};
SendGrid sub_grid(origin, size);
for (int i = 0; i < size[0]; ++i)
for (int j = 0; j < size[1]; ++j)
sub_grid(i, j) = grid(i + offset[0], j + offset[1]);
Pred pred(sub_grid);
auto begin = _pieces.begin();
auto it = std::find_if(_pieces.begin(), _pieces.end(), pred);
if (it == _pieces.end())
return;
int q = it - begin;
qDebug() << "Queuing it for processor" << q;
_queues[q].enqueue(sub_grid);
};
int size[4];
for (int i = 0; i < 2; ++i) {
if (split[i]) {
size[i] = it->origin(i) + it->size(i) - grid.origin(i);
size[2 + i] = grid.size(i) - size[i];
} else {
size[i] = grid.size(i);
size[2 + i] = 0;
}
}
extract_grid(grid.origin(), size);
if (split[0]) {
int origin[2] = {grid.origin(0) + size[0], grid.origin(1)};
int ssize[2] = {size[2], size[1]};
extract_grid(origin, ssize);
}
if (split[1]) {
int origin[2] = {grid.origin(0), grid.origin(1) + size[1]};
int ssize[2] = {size[0], size[3]};
extract_grid(origin, ssize);
}
if (split[0] && split[1]) {
int origin[2] = {grid.origin(0) + size[0], grid.origin(1) + size[1]};
int ssize[2] = {size[2], size[3]};
extract_grid(origin, ssize);
}
emit gridToSend();
}
SendGrid popQueued(int i) { return _queues[i].dequeue(); }
bool hasQueuedData(int i) { return !_queues[i].isEmpty(); }
void setGridInfo(int i, const int size[2], const int origin[2]) {
_pieces[i].setSize(size);
_pieces[i].setOrigin(origin);
}
GridState state(int i) const { return _state[i]; }
void setState(GridState ns) { for(int i = 0; i < _state.size(); ++i) _state[i] = ns; }
void setState(GridState ns, int i) { _state[i] = ns; }
signals:
void gridToSend() {}
private:
QSemaphore _pieces_sem;
size_t _nb_pieces;
std::vector<T> _data;
size_t _size[2];
std::vector<GridInfo> _pieces;
QMutex _nb_pieces_lock;
std::vector<QQueue<SendGrid>> _queues;
std::vector<GridState> _state;
};
#endif /* GRID_HH */
Event Timeline
Log In to Comment