Commit 2670fe25 authored by KLOCZKO Thibaud's avatar KLOCZKO Thibaud
Browse files

Introduce concept of ArrayItem that enable to handle array values as references.

parent 761d9036
......@@ -15,11 +15,11 @@ project(dtkDistributed)
## #################################################################
set(${PROJECT_NAME}_HEADERS
dtkObject.h
dtkDistributed
dtkDistributed.h
dtkDistributedArray.h
dtkDistributedArray.tpp
dtkDistributedArrayItem.h
dtkDistributedCommunicator.h
dtkDistributedCommunicatorPlugin
dtkDistributedCommunicatorPlugin.h
......@@ -39,7 +39,6 @@ set(${PROJECT_NAME}_HEADERS
dtkDistributedWorkerManager.h)
set(${PROJECT_NAME}_SOURCES
dtkObject.cpp
dtkDistributed.cpp
dtkDistributedCommunicator.cpp
dtkDistributedCommunicatorPluginFactory.cpp
......
......@@ -17,6 +17,7 @@
#include "dtkDistributedContainerIndexed.h"
#include "dtkDistributedContainerSequence.h"
#include "dtkDistributedArrayHandler.h"
#include "dtkDistributedArrayItem.h"
class dtkDistributedMapper;
class dtkDistributedWorker;
......@@ -28,24 +29,36 @@ class dtkDistributedWorker;
template<typename T> class dtkDistributedArray : public dtkDistributedContainerIndexed<T>, public dtkDistributedContainerSequence<T>
{
public:
dtkDistributedArray(const qlonglong& count, dtkDistributedWorker *worker);
~dtkDistributedArray(void);
inline dtkDistributedArray(const qlonglong& count, dtkDistributedWorker *worker);
~dtkDistributedArray(void);
public:
void clear(void);
inline void clear(void);
public:
bool empty(void) const;
inline bool empty(void) const;
public:
qlonglong count(void) const;
inline qlonglong count(void) const;
private:
dtkDistributedMapper *m_mapper;
dtkDistributedWorker *m_worker;
public:
inline void set(const qlonglong& index, const T& value);
public:
inline T at(const qlonglong& index) const;
public:
inline T first(void) const;
inline T last(void) const;
public:
dtkDistributedArrayItem<T> operator [] (const qlonglong& index);
public:
inline dtkDistributedMapper *mapper(void);
public:
dtkDistributedArrayHandler<T> m_handler;
dtkDistributedArrayHandler<T> *m_handler;
friend class dtkDistributedArrayHandler<T>;
......
......@@ -14,8 +14,6 @@
//#prama once
#include "dtkDistributedMapper.h"
#include "dtkDistributedWorker.h"
class dtkDistributedCommunicator;
......@@ -23,30 +21,59 @@ class dtkDistributedCommunicator;
//
// /////////////////////////////////////////////////////////////////
template<typename T> dtkDistributedArray<T>::dtkDistributedArray(const qlonglong& count, dtkDistributedWorker *worker) : m_mapper(new dtkDistributedMapper), m_worker(worker)
template<typename T> dtkDistributedArray<T>::dtkDistributedArray(const qlonglong& count, dtkDistributedWorker *worker) : m_handler(new dtkDistributedArrayHandler<T>(count, worker))
{
m_mapper->setMapping(count, m_worker->communicator()->size());
m_handler.initialize(m_worker->communicator(), m_worker->wid(), count, m_mapper->count(m_worker->wid()), m_worker->containerId());
}
template<typename T> dtkDistributedArray<T>::~dtkDistributedArray(void)
{
if (m_handler)
delete m_handler;
}
template<typename T> void dtkDistributedArray<T>::clear(void)
{
return m_handler.clear();
return m_handler->clear();
}
template<typename T> bool dtkDistributedArray<T>::empty(void) const
{
return m_handler.empty();
return m_handler->empty();
}
template<typename T> qlonglong dtkDistributedArray<T>::count(void) const
{
return m_handler.count();
return m_handler->count();
}
template<typename T> void dtkDistributedArray<T>::set(const qlonglong& index, const T& value)
{
m_handler->set(index, value);
}
template<typename T> T dtkDistributedArray<T>::at(const qlonglong& index) const
{
return m_handler->at(index);
}
template<typename T> T dtkDistributedArray<T>::first(void) const
{
return m_handler->first();
}
template<typename T> T dtkDistributedArray<T>::last(void) const
{
return m_handler->last();
}
template<typename T> dtkDistributedMapper *dtkDistributedArray<T>::mapper(void)
{
return m_handler->m_mapper;
}
template<typename T> dtkDistributedArrayItem<T> dtkDistributedArray<T>::operator [] (const qlonglong& index)
{
return dtkDistributedArrayItem<T>(this, index);
}
......@@ -17,6 +17,10 @@
template <typename T> class dtkDistributedArray;
template <typename T> class dtkDistributedArrayHandler;
class dtkDistributedCommunicator;
class dtkDistributedMapper;
class dtkDistributedWorker;
// /////////////////////////////////////////////////////////////////
//
// /////////////////////////////////////////////////////////////////
......@@ -24,10 +28,11 @@ template <typename T> class dtkDistributedArrayHandler;
template <typename T> class dtkDistributedArrayHandler
{
public:
dtkDistributedArrayHandler(void) : m_wid(-1), m_count(-1), m_buffer_id(-1), m_buffer_count(-1), m_buffer(0), m_comm(0) {;}
inline dtkDistributedArrayHandler(const qlonglong& count, dtkDistributedWorker *worker);
inline ~dtkDistributedArrayHandler(void);
public:
void initialize(dtkDistributedCommunicator *communicator, const qlonglong& wid, const qlonglong& count, const qlonglong& buffer_count, const qlonglong& buffer_id);
void initialize(void);
public:
inline void setLocalMode(void);
......@@ -40,11 +45,21 @@ public:
inline qlonglong count(void) const;
public:
inline void set(const qlonglong& index, const T& value);
public:
inline T at(const qlonglong& index) const;
public:
inline T first(void) const;
inline T last(void) const;
// /////////////////////////////////////////////////////////////////
protected:
typedef void (dtkDistributedArrayHandler<T>::*clearMethodPointer)(void);
typedef bool (dtkDistributedArrayHandler<T>::*emptyMethodPointer)(void) const;
typedef void (dtkDistributedArrayHandler<T>::*clearMethodPointer)(void);
typedef bool (dtkDistributedArrayHandler<T>::*emptyMethodPointer)(void) const;
typedef qlonglong (dtkDistributedArrayHandler<T>::*countMethodPointer)(void) const;
protected:
......@@ -64,6 +79,33 @@ protected:
// /////////////////////////////////////////////////////////////////
protected:
typedef void (dtkDistributedArrayHandler<T>::*setMethodPointer)(const qlonglong& index, const T& value);
typedef T (dtkDistributedArrayHandler<T>::*atMethodPointer)(const qlonglong& index) const;
typedef T (dtkDistributedArrayHandler<T>::*atLimitMethodPointer)(void) const;
protected:
setMethodPointer setMethod;
atMethodPointer atMethod;
atLimitMethodPointer firstMethod;
atLimitMethodPointer lastMethod;
protected:
void setLocal(const qlonglong& index, const T& value) { m_buffer[index]= value; }
void setGlobal(const qlonglong& index, const T& value);
T atLocal(const qlonglong& index) const { return m_buffer[index]; }
T atGlobal(const qlonglong& index) const;
T firstLocal(void) const { return *(m_buffer); }
T firstGlobal(void) const { return this->atGlobal(0); }
T lastLocal(void) const { return *(m_buffer + m_buffer_count - 1); }
T lastGlobal(void) const { return this->atGlobal(m_count - 1); }
// /////////////////////////////////////////////////////////////////
private:
qlonglong m_wid;
qlonglong m_count;
......@@ -75,7 +117,12 @@ private:
// /////////////////////////////////////////////////////////////////
private:
dtkDistributedMapper *m_mapper;
dtkDistributedWorker *m_worker;
dtkDistributedCommunicator *m_comm;
private:
friend class dtkDistributedArray<T>;
};
// /////////////////////////////////////////////////////////////////
......
......@@ -14,17 +14,30 @@
#pragma once
#include "dtkDistributedCommunicator.h"
#include "dtkDistributedMapper.h"
#include "dtkDistributedWorker.h"
// /////////////////////////////////////////////////////////////////
//
// /////////////////////////////////////////////////////////////////
template <typename T> void dtkDistributedArrayHandler<T>::initialize(dtkDistributedCommunicator *communicator, const qlonglong& wid, const qlonglong& count, const qlonglong& buffer_count, const qlonglong& buffer_id)
template <typename T> dtkDistributedArrayHandler<T>::dtkDistributedArrayHandler(const qlonglong& count, dtkDistributedWorker *worker) : m_mapper(new dtkDistributedMapper), m_worker(worker), m_wid(worker->wid()), m_count(count), m_comm(worker->communicator())
{
m_comm = communicator;
m_wid = wid;
m_count = count;
m_buffer_count = buffer_count;
m_buffer_id = buffer_id;
this->initialize();
}
template <typename T> dtkDistributedArrayHandler<T>::~dtkDistributedArrayHandler(void)
{
if (m_mapper)
delete m_mapper;
}
template <typename T> void dtkDistributedArrayHandler<T>::initialize(void)
{
m_mapper->setMapping(m_count, m_comm->size());
m_buffer_count = m_mapper->count(m_wid);
m_buffer_id = m_worker->containerId();
m_buffer = static_cast<T*>(m_comm->allocate(m_buffer_count, sizeof(T), m_wid, m_buffer_id));
}
......@@ -34,6 +47,12 @@ template <typename T> void dtkDistributedArrayHandler<T>::setLocalMode(void)
clearMethod = &dtkDistributedArrayHandler<T>::clearLocal;
emptyMethod = &dtkDistributedArrayHandler<T>::emptyLocal;
countMethod = &dtkDistributedArrayHandler<T>::countLocal;
setMethod = &dtkDistributedArrayHandler<T>::setLocal;
atMethod = &dtkDistributedArrayHandler<T>::atLocal;
firstMethod = &dtkDistributedArrayHandler<T>::firstLocal;
lastMethod = &dtkDistributedArrayHandler<T>::lastLocal;
}
template <typename T> void dtkDistributedArrayHandler<T>::setGlobalMode(void)
......@@ -41,6 +60,12 @@ template <typename T> void dtkDistributedArrayHandler<T>::setGlobalMode(void)
clearMethod = &dtkDistributedArrayHandler<T>::clearGlobal;
emptyMethod = &dtkDistributedArrayHandler<T>::emptyGlobal;
countMethod = &dtkDistributedArrayHandler<T>::countGlobal;
setMethod = &dtkDistributedArrayHandler<T>::setGlobal;
atMethod = &dtkDistributedArrayHandler<T>::atGlobal;
firstMethod = &dtkDistributedArrayHandler<T>::firstGlobal;
lastMethod = &dtkDistributedArrayHandler<T>::lastGlobal;
}
template <typename T> void dtkDistributedArrayHandler<T>::clear(void)
......@@ -57,3 +82,48 @@ template <typename T> qlonglong dtkDistributedArrayHandler<T>::count(void) const
{
return (this->*countMethod)();
}
template<typename T> void dtkDistributedArrayHandler<T>::set(const qlonglong& index, const T& value)
{
(this->*setMethod)(index, value);
}
template<typename T> void dtkDistributedArrayHandler<T>::setGlobal(const qlonglong& index, const T& value)
{
qint32 owner = static_cast<qint32>(m_mapper->owner(index));
qlonglong pos = m_mapper->globalToLocal(index);
m_comm->put(owner, pos, &(const_cast<T&>(value)), m_buffer_id);
}
template<typename T> T dtkDistributedArrayHandler<T>::at(const qlonglong& index) const
{
return (this->*atMethod)(index);
}
template<typename T> T dtkDistributedArrayHandler<T>::atGlobal(const qlonglong& index) const
{
qint32 owner = static_cast<qint32>(m_mapper->owner(index));
qlonglong pos = m_mapper->globalToLocal(index);
if (m_wid == owner) {
return m_buffer[pos];
} else {
T temp;
m_comm->get(owner, pos, &temp, m_buffer_id);
return temp;
}
}
template<typename T> T dtkDistributedArrayHandler<T>::first(void) const
{
return (this->*firstMethod)();
}
template<typename T> T dtkDistributedArrayHandler<T>::last(void) const
{
return (this->*lastMethod)();
}
/* dtkDistributedArrayItem.h ---
*
* Author: Thibaud Kloczko
* Created: 2013 Wed Feb 27 11:59:03 (+0100)
*/
/* Commentary:
*
*/
/* Change log:
*
*/
#pragma once
// /////////////////////////////////////////////////////////////////
//
// /////////////////////////////////////////////////////////////////
template <typename T> class dtkDistributedArrayItem
{
public:
inline dtkDistributedArrayItem(void);
inline dtkDistributedArrayItem(const dtkDistributedArrayItem<T>& other);
public:
inline ~dtkDistributedArrayItem(void);
public:
dtkDistributedArrayItem& operator = (const dtkDistributedArrayItem<T>& other);
public:
inline dtkDistributedArrayItem& operator = (const T& value);
public:
inline dtkDistributedArrayItem& operator ++ (void);
inline dtkDistributedArrayItem& operator -- (void);
inline dtkDistributedArrayItem& operator += (const T& value);
inline dtkDistributedArrayItem& operator -= (const T& value);
inline dtkDistributedArrayItem& operator *= (const T& value);
inline dtkDistributedArrayItem& operator /= (const T& value);
public:
inline T value(void) const;
private:
friend class dtkDistributedArray<T>;
inline dtkDistributedArrayItem(dtkDistributedArray<T> *array, const qlonglong& index);
private:
qlonglong m_index;
dtkDistributedArray<T> *m_array;
};
// /////////////////////////////////////////////////////////////////
template <typename T> dtkDistributedArrayItem<T>::dtkDistributedArrayItem(void) : m_index(-1), m_array(0)
{
}
template <typename T> dtkDistributedArrayItem<T>::dtkDistributedArrayItem(const dtkDistributedArrayItem& other) : m_index(other.m_index), m_array(other.m_array)
{
}
template <typename T> dtkDistributedArrayItem<T>::dtkDistributedArrayItem(dtkDistributedArray<T> *array, const qlonglong& index) : m_index(index), m_array(array)
{
}
template <typename T> dtkDistributedArrayItem<T>::~dtkDistributedArrayItem(void)
{
m_index = -1;
m_array = NULL;
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator = (const dtkDistributedArrayItem<T>& other)
{
m_index = other.m_index;
m_array = other.m_array;
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator = (const T& value)
{
m_array.set(m_index, value);
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator ++ (void)
{
m_array->set(m_index, m_array->at(m_index)++);
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator -- (void)
{
m_array->set(m_index, m_array->at(m_index)--);
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator += (const T& value)
{
m_array->set(m_index, m_array->at(m_index) + value);
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator -= (const T& value)
{
m_array->set(m_index, m_array->at(m_index) - value);
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator *= (const T& value)
{
m_array->set(m_index, m_array->at(m_index) * value);
return (*this);
}
template <typename T> dtkDistributedArrayItem<T>& dtkDistributedArrayItem<T>::operator /= (const T& value)
{
m_array->set(m_index, m_array->at(m_index) / value);
return (*this);
}
template <typename T> T dtkDistributedArrayItem<T>::value(void) const
{
return m_array->at(m_index);
}
......@@ -43,9 +43,13 @@ public:
public:
virtual bool empty(void) const = 0;
public:
// virtual bool contains(const T& value) const = 0;
public:
virtual qlonglong count(void) const = 0;
// virtual qlonglong count(const T& value) const = 0;
public:
// virtual dtkDistributedIterator<T>& iterator(void) = 0;
......
......@@ -29,11 +29,11 @@ public:
public:
// virtual void resize(const qlonglong& size) = 0;
// virtual void set(const qlonglong& index, const T& value) = 0;
virtual void set(const qlonglong& index, const T& value) = 0;
// virtual void insert(const qlonglong& index, const T& value) = 0;
// virtual void removeAt(const qlonglong& index) = 0;
public:
// virtual T at(const qlonglong& index) const = 0;
virtual T at(const qlonglong& index) const = 0;
};
......@@ -35,9 +35,9 @@ public:
/* virtual bool remove(const T& value) = 0; */
/* public: */
/* virtual T first(void) const = 0; */
/* virtual T last(void) const = 0; */
public:
virtual T first(void) const = 0;
virtual T last(void) const = 0;
/* virtual T takeFirst(void) = 0; */
/* virtual T takeLast(void) = 0; */
......
......@@ -26,32 +26,57 @@ class myWork : public dtkDistributedWork
myWork *clone(void) { return new myWork(*this); };
void run(void)
{
QTime time;
{
QTime time;
dtkDistributedCommunicator *comm = dtkDistributedWork::worker()->communicator();
dtkDistributedArray<qlonglong> array(1001, dtkDistributedWork::worker());
dtkDistributedArray<qlonglong> array(11, dtkDistributedWork::worker());
DTK_DISTRIBUTED_BEGIN_LOCAL
array.m_handler.setLocalMode();
array.clear();
qDebug() << array.empty() << dtkDistributedWork::worker()->wid();
qDebug() << array.count() << dtkDistributedWork::worker()->wid();
array.m_handler->setLocalMode();
// array.clear();
// qDebug() << array.empty() << dtkDistributedWork::worker()->wid();
// qDebug() << array.count() << dtkDistributedWork::worker()->wid();
for (qlonglong i = 0; i < array.count(); ++i)
array.set(i, array.mapper()->localToGlobal(i, dtkDistributedWork::worker()->wid()));
qDebug() << array.first() << array.last() << dtkDistributedWork::worker()->wid();
DTK_DISTRIBUTED_END_LOCAL
DTK_DISTRIBUTED_BEGIN_GLOBAL
array.m_handler.setGlobalMode();
array.clear();
qDebug() << array.empty() << dtkDistributedWork::worker()->wid();
qDebug() << array.count() << dtkDistributedWork::worker()->wid();
array.m_handler->setGlobalMode();
// array.clear();
// qDebug() << array.empty() << dtkDistributedWork::worker()->wid();
// qDebug() << array.count() << dtkDistributedWork::worker()->wid();
for (qlonglong i = 0; i < array.count(); ++i)
qDebug() << i << array.at(i) << dtkDistributedWork::worker()->wid();
qDebug() << array.first() << array.last() << dtkDistributedWork::worker()->wid();
DTK_DISTRIBUTED_END_GLOBAL
DTK_DISTRIBUTED_BEGIN_LOCAL
array.m_handler.setLocalMode();
array.clear();
qDebug() << array.empty() << dtkDistributedWork::worker()->wid();
qDebug() << array.count() << dtkDistributedWork::worker()->wid();
array.m_handler->setLocalMode();
for (qlonglong i = 0; i < array.count(); ++i)
array[i] += array.mapper()->localToGlobal(i, dtkDistributedWork::worker()->wid());
DTK_DISTRIBUTED_END_LOCAL