예제 #1
0
int exec(Memory entry_p)
{
  Instruction insn;
  unsigned long clk = 0;

  uint32_t cmod;

  if(signal(SIGINT, signal_on_sigint) == SIG_ERR) {
    err(EXIT_FAILURE, "signal SIGINT");
  }

  step_by_step = false;
  exec_finish = false;

  /* initialize internal variable */
  memory_is_fault = 0;
  memory_io_writeback = 0;
  instruction_prefetch_flush();

  /* setup system registers */
  PSR = 0;
  cmod = (PSR & PSR_CMOD_MASK);
  PCR = entry_p;
  next_PCR = 0xffffffff;
  KSPR = (Memory)STACK_DEFAULT;

#if !NO_DEBUG
  /* internal debug variable */
  traceback_next = 0;

  FLAGR.flags = 0x80000000;
  prev_FLAGR.flags = 0x80000000;

  for(unsigned int i = 0; i < breakp_next; i++) {
    NOTICE("Break point[%d]: 0x%08x\n", i, breakp[i]);
  }
#endif

  NOTICE("Execution Start: entry = 0x%08x\n", PCR);

  do {
    /* choose stack */
    if(cmod != (PSR & PSR_CMOD_MASK)) {
      SPR = !cmod ? USPR : KSPR;
    }
    cmod = (PSR & PSR_CMOD_MASK);

#if !NO_DEBUG
    /* break point check */
    for(unsigned int i = 0; i < breakp_next; i++) {
      if(PCR == breakp[i]) {
	step_by_step = true;
	break;
      }
    }
#endif

    /* instruction fetch */
    insn.value = instruction_fetch(PCR);

    if(memory_is_fault) {
      /* fault fetch */
      DEBUGINT("[FAULT] Instruction fetch: %08x\n", PCR);
      goto fault;
    }

#if !NO_DEBUG
    if(DEBUG || step_by_step) {
      puts("---");
      print_instruction(insn);
    }
#endif

    /* execution */
    insn_dispatch(insn);

  fault:
    if(memory_is_fault) {
      /* faulting memory access */
      interrupt_dispatch_nonmask(memory_is_fault);
      next_PCR = PCR;

      memory_io_writeback = 0;
      memory_is_fault = 0;
    }
    else if(memory_io_writeback) {
      /* sync io */
      io_store(memory_io_writeback);
      memory_io_writeback = 0;
    }

    /* writeback SP */
    if(cmod) {
      USPR = SPR;
    }
    else {
      KSPR = SPR;
    }

#if !NO_DEBUG
    if(step_by_step) {
      step_by_step_pause();
    }
    else {
      if(DEBUG && DEBUG_REG) { print_registers(); }
      if(DEBUG_TRACE) { print_traceback(); }
      if(DEBUG_STACK) { print_stack(SPR); }
      if(DEBUG_DPS) { dps_info(); }
    }
#endif

    if(!(clk & MONITOR_RECV_INTERVAL_MASK)) {
      if((PSR & PSR_IM_ENABLE) && IDT_ISENABLE(IDT_DPS_LS_NUM)) {
	dps_sci_recv();
      }

      if(MONITOR) {
	monitor_method_recv();
	monitor_send_queue();
      }
    }

    /* next */
    if(next_PCR != 0xffffffff) {
#if !NO_DEBUG
      /* alignment check */
      if(next_PCR & 0x3) {
	abort_sim();
	errx(EXIT_FAILURE, "invalid branch addres. %08x", next_PCR);
      }
#endif

      PCR = next_PCR;
      next_PCR = 0xffffffff;
    }
    else {
      PCR += 4;
    }

    /* interrupt check */
    interrupt_dispatcher();

#if !NO_DEBUG
    /* for invalid flags checking */
    prev_FLAGR.flags = FLAGR.flags;
    FLAGR._invalid |= 1;
#endif

    /* next cycle */
    clk++;

  } while(!(PCR == 0 && GR[31] == 0 && DEBUG_EXIT_B0) && !exec_finish);
  /* DEBUG_EXIT_B0: exit if b rret && rret == 0 */

  NOTICE("---- Program Terminated ----\n");
  print_instruction(insn);
  print_registers();

  return 0;
}
예제 #2
0
void FEM_Coarsen_Operation(FEM_Operation_Data *coarsen_data, coarsenData &operation){
  double *coord = coarsen_data->coord;
  int tri,nodeToThrow,nodeToKeep,n1,n2;
  int *connData = coarsen_data->connData;
  int *validNodeData = coarsen_data->validNodeData;
  int *validElemData = coarsen_data->validElemData;
  int *nodeBoundaryData = coarsen_data->nodeBoundaryData;
  FEM_Attribute *sparseBoundaryAttr = coarsen_data->sparseBoundaryAttr;
  AllocTable2d<int> *sparseBoundaryTable;

  switch(operation.type){
  case COLLAPSE: 
    {
      tri = operation.data.cdata.elemID;
      nodeToKeep = operation.data.cdata.nodeToKeep;
      nodeToThrow = operation.data.cdata.nodeToDelete;
      int opNode = 0;
      for (int i=0; i<3; i++) {
	if ((connData[3*tri+i] != nodeToThrow) &&
	    (connData[3*tri+i] != nodeToKeep)) {
	  opNode = connData[3*tri+i];
	  break;
	}
      }
      CkPrintf("Collapse %d, nodeToKeep %d, nodeToThrow %d, opNode %d\n",
	       tri, nodeToKeep, nodeToThrow, opNode);
      sparseBoundaryTable = &(((FEM_DataAttribute *)sparseBoundaryAttr)->getInt());
      int delEdgeIdx = coarsen_data->nodes2sparse->get(intdual(nodeToThrow,opNode))-1;
      int keepEdgeIdx = coarsen_data->nodes2sparse->get(intdual(nodeToKeep,opNode))-1;
      int delBC = ((*sparseBoundaryTable)[delEdgeIdx])[0];
      int keepBC = ((*sparseBoundaryTable)[keepEdgeIdx])[0];
      if (delBC > keepBC) {
	((*sparseBoundaryTable)[keepEdgeIdx])[0] = delBC;
      }
      
      if(operation.data.cdata.flag & 0x1 || operation.data.cdata.flag & 0x2){
	interpolateNode(coarsen_data->node,nodeToKeep,nodeToThrow,nodeToKeep,operation.data.cdata.frac);
	coord[2*nodeToKeep] = operation.data.cdata.newX;
	coord[2*nodeToKeep+1] = operation.data.cdata.newY;
	validNodeData[nodeToThrow] = 0;
	validNodeData[nodeToKeep] = 1;
	DEBUGINT(printf("---------Collapse <%d,%d> invalidating node %d and element %d \n",nodeToKeep,nodeToThrow,nodeToThrow,tri));
	if(coarsen_data->validEdge){	
	  int sidx = coarsen_data->nodes2sparse->get(intdual(nodeToKeep,nodeToThrow))-1;
	  coarsen_data->nodes2sparse->remove(intdual(nodeToKeep,nodeToThrow));
	  (*(coarsen_data->validEdge))[sidx][0] = 0;
	  DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",sidx,nodeToKeep,nodeToThrow));
	  if (delEdgeIdx >=0) {
	    coarsen_data->nodes2sparse->remove(intdual(opNode,nodeToThrow));
	    (*(coarsen_data->validEdge))[delEdgeIdx][0] = 0;
	    DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",delEdgeIdx,opNode,nodeToThrow));
	  }
	}	
      }
      else {
	if (delEdgeIdx >=0) {
	  coarsen_data->nodes2sparse->remove(intdual(opNode,nodeToThrow));
	  (*(coarsen_data->validEdge))[delEdgeIdx][0] = 0;
	  DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",delEdgeIdx,opNode,nodeToThrow));
	}	
      }
      validElemData[tri] = 0;
      connData[3*tri] = connData[3*tri+1] = connData[3*tri+2] = -1;
    }
    break;
  case	UPDATE:
    if(validNodeData[operation.data.udata.nodeID]){
      coord[2*(operation.data.udata.nodeID)] = operation.data.udata.newX;
      coord[2*(operation.data.udata.nodeID)+1] = operation.data.udata.newY;
      if(nodeBoundaryData){
	nodeBoundaryData[operation.data.udata.nodeID]=operation.data.udata.boundaryFlag;
      }
    }else{
      DEBUGINT(printf("[%d] WEIRD -- update operation for invalid node %d \n",CkMyPe(),operation.data.udata.nodeID));
    }
    break;
  case REPLACE:
    if(validElemData[operation.data.rddata.elemID]){
      if(connData[3*operation.data.rddata.elemID+operation.data.rddata.relnodeID] == operation.data.rddata.oldNodeID){
	connData[3*operation.data.rddata.elemID+operation.data.rddata.relnodeID] = operation.data.rddata.newNodeID;
	if(validNodeData[operation.data.rddata.oldNodeID]){
	  validNodeData[operation.data.rddata.oldNodeID]=0;
	}
	if(coarsen_data->validEdge){
	  //remove the edges containing oldNodeID and add edges containing newNodeID in the nodes2sparse hashtable
	  //update the connectivity information of the edges
	  for(int i=0;i<3;i++){
	    //find the two nodes apart from the one being replaced
	    if(i != operation.data.rddata.relnodeID){
	      int otherNode = connData[3*operation.data.rddata.elemID+i];
	      int edgeIdx = coarsen_data->nodes2sparse->get(intdual(operation.data.rddata.oldNodeID,otherNode))-1;
	      if(edgeIdx >= 0){
		//The edge connectivity has not been updated on this processor
		coarsen_data->nodes2sparse->remove(intdual(operation.data.rddata.oldNodeID,otherNode));
		DEBUGINT(printf("---- Deleting edge %d between nodes %d and %d \n",edgeIdx,operation.data.rddata.oldNodeID,otherNode));
		coarsen_data->nodes2sparse->put(intdual(operation.data.rddata.newNodeID,otherNode)) = edgeIdx+1;
		DEBUGINT(printf("---- Adding edge %d between nodes %d and %d \n",edgeIdx,operation.data.rddata.newNodeID,otherNode));
		(*(coarsen_data->sparseConnTable))[edgeIdx][0] = otherNode;
		(*(coarsen_data->sparseConnTable))[edgeIdx][1] = operation.data.rddata.newNodeID;
	      }	
	    }
	  }
	}
      }else{
	DEBUGINT(printf("[%d] WEIRD -- REPLACE operation for element %d specifies different node number %d \n",CkMyPe(),operation.data.rddata.elemID,operation.data.rddata.oldNodeID));
      }
    }else{
      DEBUGINT(printf("[%d] WEIRD -- REPLACE operation for invalid element %d \n",CkMyPe(),operation.data.rddata.elemID));
    }
    DEBUGINT(printf("---------Replace invalidating node %d with %d in element %d\n",operation.data.rddata.oldNodeID,operation.data.rddata.newNodeID,operation.data.rddata.elemID));
    break;
  default:
    DEBUGINT(printf("[%d] WEIRD -- COARSENDATA type == invalid \n",CkMyPe()));
    CmiAbort("COARSENDATA type == invalid");
  }			
};
예제 #3
0
void FEM_Refine_Operation(FEM_Refine_Operation_Data *data,refineData &op){
  
  int meshID = data->meshID;
  int nodeID = data->nodeID;
  int sparseID = data->sparseID;
  CkVec<FEM_Attribute *> *attrs = data->attrs;
  CkVec<FEM_Attribute *> *elemattrs = data->elemattrs;
  CkHashtableT<intdual,int> *newnodes=data->newnodes;
  CkHashtableT<intdual,int> *nodes2sparse = data->nodes2sparse;
  FEM_Attribute *sparseConnAttr = data->sparseConnAttr, *sparseBoundaryAttr = data->sparseBoundaryAttr;
  AllocTable2d<int> *connTable = data->connTable;
  double *coord = data->coord;
  AllocTable2d<int> *sparseConnTable, *sparseBoundaryTable;
  CkVec<FEM_Attribute *> *sparseattrs = data->sparseattrs;
  /*
  FEM_DataAttribute *boundaryAttr = (FEM_DataAttribute *)data->node->lookup(FEM_BOUNDARY,"split");
  if(boundaryAttr != NULL){
  AllocTable2d<int> &boundaryTable = boundaryAttr->getInt();
  printf(" Node Boundary flags \n");
  for(int i=0;i<data->node->size();i++){
  printf("Node %d flag %d \n",i,boundaryTable[i][0]);
  }
  }
  */
  
  int tri=op.tri,A=op.A,B=op.B,C=op.C,D=op.D;
  double frac=op.frac;
  // current number of nodes in the mesh
  int *connData = connTable->getData();
  int flags=op.flag;
    
  if((flags & 0x1) || (flags & 0x2)){
    //new node 
    DEBUGINT(CkPrintf("---- Adding node %d\n",D));			
    /*	lastA=A; lastB=B; lastD=D;*/
    if (A>=data->cur_nodes) CkAbort("Calculated A is invalid!");
    if (B>=data->cur_nodes) CkAbort("Calculated B is invalid!");
    if(D >= data->cur_nodes){
      data->node->setLength(D+1);
      data->cur_nodes = D+1;
    }	
    for(int i=0;i<attrs->size();i++){
      FEM_Attribute *a = (FEM_Attribute *)(*attrs)[i];
      if(a->getAttr()<FEM_ATTRIB_TAG_MAX){
	FEM_DataAttribute *d = (FEM_DataAttribute *)a;
	d->interpolate(A,B,D,frac);
      }else{
	/* Boundary value of new node D should be boundary value of the edge
	   (sparse element) that contains the two nodes A & B. */
	if(a->getAttr() == FEM_BOUNDARY){
	  if(sparseID != -1){
	    int sidx = nodes2sparse->get(intdual(A,B))-1;
	    if(sidx == -1){
	      CkAbort("no sparse element between these 2 nodes, are they really connected ??");
	    }
	    sparseBoundaryTable = &(((FEM_DataAttribute *)sparseBoundaryAttr)->getInt());
	    
	    int boundaryVal = ((*sparseBoundaryTable)[sidx])[0];
	    
	    (((FEM_DataAttribute *)a)->getInt()[D])[0] = boundaryVal;
	  }else{
	    /* if sparse elements don't exist, just do simple interpolation */
	    FEM_DataAttribute *d = (FEM_DataAttribute *)a;
	    d->interpolate(A,B,D,frac);
	  }
	}
      }	
    }
    int AandB[2];
    AandB[0]=A;
    AandB[1]=B;
    /* Add a new node D between A and B */
    IDXL_Add_entity(FEM_Comm_shared(meshID,nodeID),D,2,AandB);
    double Dx = coord[2*A]*(1-frac)+frac*coord[2*B];
    double Dy = coord[2*A+1]*(1-frac)+frac*coord[2*B+1];
    data->coordVec->push_back(Dx);
    data->coordVec->push_back(Dy);
    newnodes->put(intdual(A,B))=D;
    /* add the new sparse element <D,B> and modify the connectivity of the old
       one from <A,B> to <A,D> and change the hashtable to reflect that change
    */
    if(sparseID != -1){
      int oldsidx = nodes2sparse->get(intdual(A,B))-1;
      int newsidx = data->sparse->size();
      data->sparse->setLength(newsidx+1);
      for(int satt = 0;satt<sparseattrs->size();satt++){
	if((*sparseattrs)[satt]->getAttr() == FEM_CONN){
	  /* change the conn of the old sparse to A,D and new one to B,D */
	  sparseConnTable = &(((FEM_IndexAttribute *)sparseConnAttr)->get());
	  int *oldconn = (*sparseConnTable)[oldsidx];
	  int *newconn = (*sparseConnTable)[newsidx];
	  oldconn[0] = A;
	  oldconn[1] = D;
	  newconn[0] = D;
	  newconn[1] = B;
	  //printf("<%d,%d> edge being split into <%d,%d> <%d,%d> \n",A,B,A,D,D,B);
	}else{
	  /* apart from conn copy everything else */
	  FEM_Attribute *attr = (FEM_Attribute *)(*sparseattrs)[satt];
	  attr->copyEntity(newsidx,*attr,oldsidx);
	}
      }
      /* modify the hashtable - delete the old edge and the new ones */
      nodes2sparse->remove(intdual(A,B));
      nodes2sparse->put(intdual(A,D)) = oldsidx+1;
      nodes2sparse->put(intdual(D,B)) = newsidx+1;
    }
  }
  //add a new triangle
  /*TODO: replace  FEM_ELEM with parameter*/
  int newTri =	op._new;
  int cur_elements  = FEM_Mesh_get_length(data->meshID,data->elemID);
  DEBUGINT(CkPrintf("---- Adding triangle %d after splitting %d \n",newTri,tri));
  if(newTri >= cur_elements){
    data->elem->setLength(newTri+1);
  }	
  D = newnodes->get(intdual(A,B));
  
  for(int j=0;j<elemattrs->size();j++){
    if((*elemattrs)[j]->getAttr() == FEM_CONN){
      DEBUGINT(CkPrintf("elem attr conn code %d \n",(*elemattrs)[j]->getAttr()));
      //it is a connectivity attribute.. get the connectivity right
      FEM_IndexAttribute *connAttr = (FEM_IndexAttribute *)(*elemattrs)[j];
      AllocTable2d<int> &table = connAttr->get();
      DEBUGINT(CkPrintf("Table of connectivity attribute starts at %p width %d \n",table[0],connAttr->getWidth()));
      int *oldRow = table[tri];
      int *newRow = table[newTri];
      for (int i=0;i<3;i++){
	if (oldRow[i]==A){
	  oldRow[i]=D;	
	  DEBUGINT(CkPrintf("In triangle %d %d replaced by %d \n",tri,A,D));
	}
      }	
      for (int i=0; i<3; i++) {
	if (oldRow[i] == B){
	  newRow[i] = D;
	}	
	else if (oldRow[i] == C){
	  newRow[i] = C;
	}	
	else if (oldRow[i] == D){
	  newRow[i] = A;
	}	
      }
      DEBUGINT(CkPrintf("New Triangle %d  (%d %d %d) conn %p\n",newTri,newRow[0],newRow[1],newRow[2],newRow));
    }else{
      FEM_Attribute *elattr = (FEM_Attribute *)(*elemattrs)[j];
      if(elattr->getAttr() < FEM_ATTRIB_FIRST){ 
	elattr->copyEntity(newTri,*elattr,tri);
      }
    }
  }
  
  if(sparseID != -1){ /* add sparse element (edge between C and D) */
    int cdidx = data->sparse->size();
    data->sparse->setLength(cdidx+1);
    for(int satt = 0; satt < sparseattrs->size();satt++){
      if((*sparseattrs)[satt]->getAttr() == FEM_CONN){
	sparseConnTable = &(((FEM_IndexAttribute *)sparseConnAttr)->get());
	int *cdconn = (*sparseConnTable)[cdidx];
	cdconn[0]=C;
	cdconn[1]=D;
      }
      if((*sparseattrs)[satt]->getAttr() == FEM_BOUNDARY){
	/* An edge connecting C and D has to be an internal edge */
	sparseBoundaryTable = &(((FEM_DataAttribute *)sparseBoundaryAttr)->getInt());
	((*sparseBoundaryTable)[cdidx])[0] = 0;
      }
    }
    if(data->validEdge){
      (*(data->validEdge))[cdidx][0] = 1;
    }
    nodes2sparse->put(intdual(C,D)) = cdidx+1;
  }
}
예제 #4
0
void FEM_REFINE2D_Coarsen(int meshID,int nodeID,double *coord,int elemID,double *desiredAreas,int sparseID){
  int nnodes = FEM_Mesh_get_length(meshID,nodeID);
  int nelems = FEM_Mesh_get_length(meshID,elemID);
  int nodeCount=0,elemCount=0;
  
  /* The attributes of the different entities */
  FEM_Entity *node=FEM_Entity_lookup(meshID,nodeID,"REFINE2D_Mesh");
  CkVec<FEM_Attribute *> *attrs = node->getAttrVec();
  FEM_Attribute *validNodeAttr = node->lookup(FEM_VALID,"FEM_COARSEN");
  FEM_Attribute *nodeBoundaryAttr = node->lookup(FEM_BOUNDARY,"FEM_COARSEN");
  if(!nodeBoundaryAttr){
    printf("Warning:- no boundary flags for nodes \n");
  }
  
  FEM_Entity *elem = FEM_Entity_lookup(meshID,elemID,"REFIN2D_Mesh_elem");
  CkVec<FEM_Attribute *> *elemattrs = elem->getAttrVec();
  FEM_Attribute *validElemAttr = elem->lookup(FEM_VALID,"FEM_COARSEN");
  
  FEM_Attribute *connAttr = elem->lookup(FEM_CONN,"REFINE2D_Mesh");
  if(connAttr == NULL){
    CkAbort("Grrrr element without connectivity \n");
  }
  AllocTable2d<int> &connTable = ((FEM_IndexAttribute *)connAttr)->get();
  AllocTable2d<int>&validNodeTable = ((FEM_DataAttribute *)validNodeAttr)->getInt();
  AllocTable2d<int>&validElemTable = ((FEM_DataAttribute *)validElemAttr)->getInt();
  FEM_Operation_Data *coarsen_data = new FEM_Operation_Data;
  coarsen_data->node = (FEM_Node *)node;
  coarsen_data->coord = coord;
  int *connData = coarsen_data->connData= connTable.getData();
  int *validNodeData = coarsen_data->validNodeData = validNodeTable.getData();
  int *validElemData = coarsen_data->validElemData = validElemTable.getData();
  /* Extract the data for node boundaries */
  int *nodeBoundaryData= coarsen_data->nodeBoundaryData =NULL;
  if(nodeBoundaryAttr){
    AllocTable2d<int> &nodeBoundaryTable = ((FEM_DataAttribute *)nodeBoundaryAttr)->getInt();
    nodeBoundaryData = coarsen_data->nodeBoundaryData = nodeBoundaryTable.getData();
  }
  
  for(int k=0;k<nnodes;k++){
    int valid = validNodeData[k];
    if(validNodeData[k]){
      nodeCount++;
    }
  }
  for(int k=0;k<nelems;k++){
    if(validElemData[k]){
      elemCount++;
    }
  }
  
  /* populate the hashtable from nodes2edges with the valid edges */
  CkHashtableT<intdual,int> nodes2sparse(nelems);
  coarsen_data->nodes2sparse = &nodes2sparse;
  FEM_Attribute *sparseBoundaryAttr;
  if(sparseID != -1){
    FEM_Entity *sparse = FEM_Entity_lookup(meshID,sparseID,"Coarsen_sparse");
    FEM_DataAttribute *validEdgeAttribute = (FEM_DataAttribute *)sparse->lookup(FEM_VALID,"Coarsen_sparse");
    FEM_IndexAttribute *sparseConnAttribute = (FEM_IndexAttribute *)sparse->lookup(FEM_CONN,"Coarsen_sparse");
    AllocTable2d<int> *sparseConnTable = coarsen_data->sparseConnTable = &(sparseConnAttribute->get());
    coarsen_data->sparseBoundaryAttr = sparseBoundaryAttr = sparse->lookup(FEM_BOUNDARY,"REFINE2D_Mesh_sparse");
    if(sparseBoundaryAttr == NULL){
      CkAbort("Specified sparse elements without boundary conditions");
    }

    
    if(validEdgeAttribute){
      coarsen_data->validEdge = &(validEdgeAttribute->getInt());
    }else{
      coarsen_data->validEdge = NULL;
    }
    /* since the default value in the hashtable is 0, to distinguish between 
       uninserted keys and the sparse element with index 0, the index of the 
       sparse elements is incremented by 1 while inserting. */
    printf("[%d] Sparse elements\n",FEM_My_partition());
    for(int j=0;j<sparse->size();j++){
      if(coarsen_data->validEdge == NULL || (*(coarsen_data->validEdge))[j][0]){
	int *cdata = (*sparseConnTable)[j];
	printf("%d < %d,%d > \n",j,cdata[0],cdata[1]);
	nodes2sparse.put(intdual(cdata[0],cdata[1])) = j+1;
      }	
    }
  }else{
    coarsen_data->validEdge = NULL;
  }
  
  DEBUGINT(printf("coarsen %d %d \n",nodeCount,elemCount));	
  REFINE2D_Coarsen(nodeCount,coord,elemCount,desiredAreas,coarsen_data);
  int nCollapses = REFINE2D_Get_Collapse_Length();
  
  
  for(int i=0;i<nnodes;i++){
    int valid = validNodeData[i];
  }
  delete coarsen_data;
}  
예제 #5
0
void FEM_REFINE2D_Split(int meshID,int nodeID,double *coord,int elemID,double *desiredAreas,int sparseID){
  int nnodes = FEM_Mesh_get_length(meshID,nodeID);
  int nelems = FEM_Mesh_get_length(meshID,elemID);
  int actual_nodes = nnodes, actual_elems = nelems;
  
  FEM_Refine_Operation_Data refine_data;
  refine_data.meshID = meshID;
  refine_data.nodeID = nodeID;
  refine_data.sparseID = sparseID;
  refine_data.elemID = elemID;
  refine_data.cur_nodes = FEM_Mesh_get_length(meshID,nodeID);
  
  /*Copy the cordinates of the nodes into a vector, 
    the cordinates of the new nodes will be inserted
    into this vector and will be used to sort all the
    nodes on the basis of the distance from origin
  */
  CkVec<double> coordVec;
  for(int i=0;i<nnodes*2;i++){
    coordVec.push_back(coord[i]);
  }
  refine_data.coordVec = &coordVec;
  refine_data.coord = coord;
  
  /*find out the attributes of the node */
  FEM_Entity *e=refine_data.node = FEM_Entity_lookup(meshID,nodeID,"REFINE2D_Mesh");
  CkVec<FEM_Attribute *> *attrs = refine_data.attrs = e->getAttrVec();
  /* 
  FEM_DataAttribute *boundaryAttr = (FEM_DataAttribute *)e->lookup(FEM_BOUNDARY,"split");
  if(boundaryAttr != NULL){
	AllocTable2d<int> &boundaryTable = boundaryAttr->getInt();
	printf(" Node Boundary flags \n");
	for(int i=0;i<nnodes;i++){
		printf("Node %d flag %d \n",i,boundaryTable[i][0]);
	}
  }
  */
  FEM_Entity *elem = refine_data.elem = FEM_Entity_lookup(meshID,elemID,"REFIN2D_Mesh_elem");
  CkVec<FEM_Attribute *> *elemattrs = refine_data.elemattrs = elem->getAttrVec();
  
  FEM_Attribute *connAttr = elem->lookup(FEM_CONN,"REFINE2D_Mesh");
  if(connAttr == NULL){
    CkAbort("Grrrr element without connectivity \n");
  }
  AllocTable2d<int> &connTable = ((FEM_IndexAttribute *)connAttr)->get();
  refine_data.connTable = &connTable;
  
  //hashtable to store the new node number as a function of the two old numbers
  CkHashtableT<intdual,int> newnodes(nnodes);
  refine_data.newnodes = &newnodes;
  
  /* Get the FEM_BOUNDARY data of sparse elements and load it into a hashtable
    indexed by the 2 node ids that make up the edge. The data in the hashtable
    is the index number of the sparse element */
  FEM_Entity *sparse;
  CkVec<FEM_Attribute *> *sparseattrs;
  FEM_Attribute *sparseConnAttr, *sparseBoundaryAttr;
  AllocTable2d<int> *sparseConnTable, *sparseBoundaryTable;
  CkHashtableT<intdual,int> nodes2sparse(nelems);
  refine_data.nodes2sparse = &nodes2sparse;
  
  if(sparseID != -1){
    sparse = refine_data.sparse = FEM_Entity_lookup(meshID,sparseID,"REFINE2D_Mesh_sparse");
    refine_data.sparseattrs = sparseattrs = sparse->getAttrVec();
    refine_data.sparseConnAttr = sparseConnAttr = sparse->lookup(FEM_CONN,"REFINE2D_Mesh_sparse");
    sparseConnTable = &(((FEM_IndexAttribute *)sparseConnAttr)->get());
    refine_data.sparseBoundaryAttr = sparseBoundaryAttr = sparse->lookup(FEM_BOUNDARY,"REFINE2D_Mesh_sparse");
    if(sparseBoundaryAttr == NULL){
      CkAbort("Specified sparse elements without boundary conditions");
    }
    FEM_DataAttribute *validEdgeAttribute = (FEM_DataAttribute *)sparse->lookup(FEM_VALID,"REFINE2D_Mesh_sparse");
    if(validEdgeAttribute){
      refine_data.validEdge = &(validEdgeAttribute->getInt());
    }else{
      refine_data.validEdge = NULL;
    }
    /* since the default value in the hashtable is 0, to distinguish between 
       uninserted keys and the sparse element with index 0, the index of the 
       sparse elements is incremented by 1 while inserting. */
    //		printf("[%d] Sparse elements\n",FEM_My_partition());
    for(int j=0;j<sparse->size();j++){
      if(refine_data.validEdge == NULL || (*(refine_data.validEdge))[j][0]){
	int *cdata = (*sparseConnTable)[j];
	//		printf("%d < %d,%d > \n",j,cdata[0],cdata[1]);
	nodes2sparse.put(intdual(cdata[0],cdata[1])) = j+1;
      }	
    }
  }else{
    printf("Edge boundary conditions not passed into FEM_REFINE2D_Split \n");
  }
  
  //count the actual number of nodes and elements
  if(refine_data.node->lookup(FEM_VALID,"refine2D_splilt") != NULL){
    AllocTable2d<int> &validNodeTable = ((FEM_DataAttribute *)(refine_data.node->lookup(FEM_VALID,"refine2D_splilt")))->getInt();
    actual_nodes = countValidEntities(validNodeTable.getData(),nnodes);
  }
  if(refine_data.elem->lookup(FEM_VALID,"refine2D_splilt") != NULL){
    AllocTable2d<int> &validElemTable = ((FEM_DataAttribute *)(refine_data.elem->lookup(FEM_VALID,"refine2D_splilt")))->getInt();
    actual_elems = countValidEntities(validElemTable.getData(),nelems);
  }
  
  DEBUGINT(printf("%d %d \n",nnodes,nelems));	
  REFINE2D_Split(actual_nodes,coord,actual_elems,desiredAreas,&refine_data);
  
  int nSplits= refine_data.nSplits = REFINE2D_Get_Split_Length();
  DEBUGINT(printf("called REFINE2D_Split nSplits = %d \n",nSplits));
  
  if(nSplits == 0){
    return;
  }
  
  for(int split = 0;split < nSplits;split++){
    refineData op;
    REFINE2D_Get_Split(split,&op);
    FEM_Refine_Operation(&refine_data,op);
  }
  
  DEBUGINT(printf("Cordinate list length %d according to FEM %d\n",coordVec.size()/2,FEM_Mesh_get_length(meshID,nodeID)));
  IDXL_Sort_2d(FEM_Comm_shared(meshID,nodeID),coordVec.getVec());
  int read = FEM_Mesh_is_get(meshID) ;
  assert(read);
}