/*
 * $Id: Space2PERandom.java,v 1.4 2000/06/15 13:55:48 yamauchi Exp $
 *     (M\pi)^2 : Pseudo Random Allocation Implementation
 *	Copyright 1999 By YAMAUCHI Hitoshi 山内 斉 
 *	@author YAMAUCHI Hitoshi 山内 斉
 *	
 * original source spc2PE.h spc2PE.cc
 *
 *	部分空間と PE のマッピング : Pseudo-Random Allocation
 * 
 * 1999年8月 4日(水)
 */

package jp.ac.tohoku.is.archi.mpi2.common;

import  jp.ac.tohoku.is.archi.mpi2.util.IntVec3;
import  jp.ac.tohoku.is.archi.mpi2.util.Assert;

public final class Space2PERandom extends Space2PE {
    public Space2PERandom()
    {
	super();
	this.mNumberOfPE 	= new int[3];
	this.mNumberOfSPCof1PE	= new int[3];
    }

    public Space2PERandom(Space2PERandom rhs)
    {
	this.mSystemDimension = rhs.mSystemDimension;
	this.mNumberOfPE 	= new int[3];
	this.mNumberOfSPCof1PE	= new int[3];
	for(int i = 0; i < 3; i++)
	{
	    this.mNumberOfPE[i]		= rhs.mNumberOfPE[i];
	    this.mNumberOfSPCof1PE[i] 	= rhs.mNumberOfSPCof1PE[i];
	}
	this.mSubDivNum = rhs.mSubDivNum;
	this.mPEID	= new IntVec3(rhs.mPEID);
    }

    /**
     * init for pseudo-random allocation
     */
    public void init(IntVec3 numberOfPEs, int subdivnum, IntVec3 PEid)
    {
	// random allocation に次元は関係ないが
	// 現在は 1 次元のみ
	this.mSystemDimension = getSystemDimension(numberOfPEs); 
	if((this.mSystemDimension != 1)    ||
	   (numberOfPEs.get(IntVec3.Y) > 1)||(numberOfPEs.get(IntVec3.Z) > 1))
	{
	    String s = "Error! : illegal dimension spc2PERandomClass.init" +
		" only xdir 1 dim is permitted, but now (" + numberOfPEs +").";
	    throw new RuntimeException(s);
	    // commMpi2_exit(1);
	}
	
	this.mSubDivNum	   = subdivnum;    
	if(subdivnum < 1)
	{
	    String s = "Error! : illegal subdivnum spc2PERandomClass.init" +
		subdivnum;
	    throw new RuntimeException(s);
	    // commMpi2_exit(1);
	}
	for(int i = 0; i < 3; i++)
	{
	    this.mNumberOfPE[i]  = numberOfPEs.get(i);
	    // random mapping ではどの PE がどれだけの空間を持つのか
	    // も不明である。そのため全て持つ
	    this.mNumberOfSPCof1PE[i] = subdivnum;
	}
	this.mPEID = new IntVec3(PEid);
    }
    
    /**
     * hash function
     *   ここで random なマッピングをシミュレートする
     */
    private final int spcMapHash(IntVec3 spcPos)
    {
	int x = spcPos.get(IntVec3.X);
	int y = spcPos.get(IntVec3.Y);
	int z = spcPos.get(IntVec3.Z);
	return((x * 3 + y * 5 + z * 7) % (this.mNumberOfPE[0]));
    }
    
    /** 
     * spcpos -> PEID
     */
    public IntVec3 getNewPEIDfromSpcPos(IntVec3 spcPos)
    {
	return(new IntVec3(this.spcMapHash(spcPos), 0, 0));
    }
    
    /**
     * random では local 空間を圧縮する方法がない可能性があるので全てを保
     * 持する。 
     * local Idx = 物体情報を担当空間分のみとした場合の PE 内部の index
     */
    public IntVec3 getNewLocalIdxFromSpcPos(IntVec3 spcPos)
    {
	return(spcPos);
    }	
}








