//------------------------------------------------------------
// $Id: spc2PE.h,v 1.1.1.1 1999/11/25 06:26:09 yamauchi Exp $
//------------------------------------------------------------
//	spc2PE.h 
//	部分空間と PE のマッピング
//	平成８年７月１１日(木)
//	Copyright (C) 1996--1998 YAMAUCHI Hitoshi 山内 斉
//  allocation scheme によって異なる関数を呼び出したい。
//  これを allocation scheme ごとに異なる mapper object としてモデル化
//  し、それを仮想関数で実現してみる。 平成８年７月１１日(木) 
//------------------------------------------------------------
#ifndef _spc2PE_h
#define _spc2PE_h 1

#include "IntVec3.h"

//------------------------------
// base class
//------------------------------
class spc2PEBaseClass {
private:
    spc2PEBaseClass(const spc2PEBaseClass& rhs);
    const spc2PEBaseClass& operator=(const spc2PEBaseClass& rhs);
    
protected:
    int mSystemDimension;
    int mNumberOfPE[3];		// 3 is [X, Y, Z]
    int mNumberOfSPCof1PE[3];	// 3 is [X, Y, Z] 1 つの PE の持つ空間数
    int mSubDivNum;	
    IntVec3 mPEID;

protected:
    void baseprint(void);
    
public:
    spc2PEBaseClass(void);
    virtual ~spc2PEBaseClass(void){};
    virtual const IntVec3 getPEIDfromSpcPos(const IntVec3& spcPos) = 0;
    // local Idx = 物体情報を担当空間分のみとした場合の PE 内部の index
    virtual const IntVec3 getLocalIdxFromSpcPos(const IntVec3& spcPos) = 0;
    virtual void print(void) = 0;
};


//------------------------------
// block allocation
//------------------------------
class spc2PEBlockClass : public spc2PEBaseClass {
private:
    const spc2PEBlockClass& operator=(const spc2PEBlockClass& rhs);

protected:
public:
    spc2PEBlockClass(void);
    spc2PEBlockClass(const spc2PEBlockClass& rhs);
    void init(const IntVec3& numberOfPEs, int subdivnum, const IntVec3& PEid);

    virtual const IntVec3 getPEIDfromSpcPos(const IntVec3& spcPos);
    virtual const IntVec3 getLocalIdxFromSpcPos(const IntVec3& spcPos);
    virtual void print(void);
};


//------------------------------
// distributed allocation
//------------------------------
class spc2PEDistributeClass : public spc2PEBaseClass {
private:
    const spc2PEDistributeClass& operator=(const spc2PEDistributeClass& rhs);

protected:
public:
    spc2PEDistributeClass(void);
    spc2PEDistributeClass(const spc2PEDistributeClass& rhs);
    void init(const IntVec3& numberOfPEs, int subdivnum, const IntVec3& PEid);

    virtual const IntVec3 getPEIDfromSpcPos(const IntVec3& spcPos);
    virtual const IntVec3 getLocalIdxFromSpcPos(const IntVec3& spcPos);
    virtual void print(void);
};


//------------------------------
// skewed distributed allocation
//------------------------------
class spc2PESkewClass : public spc2PEBaseClass {
private:
    const spc2PESkewClass& operator=(const spc2PESkewClass& rhs);

protected:
    // 平面がどちらを向いているか
    // 	   1次元 ... PE の並ぶ方向
    // 	   2次元 ... PE の並んだ平面の法線方向
    enum plane_dir_e { PE_X_DIR, PE_Y_DIR, PE_Z_DIR, PE_ELSE_DIR };
    enum plane_dir_e mPlaneDir;	

protected:
    // local functions of skewed distributed allocation scheme
    inline const IntVec3 getPE1DID(const IntVec3& spcpos) const;
    inline const IntVec3 getPE2DID(const IntVec3& spcpos) const;
    inline const IntVec3 getPE1DLocalSpaceIndex(const IntVec3& spcpos) const;
    inline const IntVec3 getPE2DLocalSpaceIndex(const IntVec3& spcpos) const;

public:
    spc2PESkewClass(void);
    spc2PESkewClass(const spc2PESkewClass& rhs);
    void init(const IntVec3& numberOfPEs, int subdivnum, const IntVec3& PEid);

    virtual const IntVec3 getPEIDfromSpcPos(const IntVec3& spcPos);
    virtual const IntVec3 getLocalIdxFromSpcPos(const IntVec3& spcPos);
    virtual void print(void);
};

//------------------------------
// random allocation
//------------------------------
class spc2PERandomClass : public spc2PEBaseClass {
private:
    const spc2PERandomClass& operator=(const spc2PERandomClass& rhs);

protected:
    // local functions of random allocation scheme
    inline int spcMapHash(const IntVec3& spcPos);

public:
    spc2PERandomClass(void);
    spc2PERandomClass(const spc2PERandomClass& rhs);
    void init(const IntVec3& numberOfPEs, int subdivnum, const IntVec3& PEid);

    virtual const IntVec3 getPEIDfromSpcPos(const IntVec3& spcPos);
    virtual const IntVec3 getLocalIdxFromSpcPos(const IntVec3& spcPos);
    virtual void print(void);
};


#endif				// #ifndef _spc2PE_h
