in_list
objectsAllocated(SgStatement *statement, StopCond stopCond)
   {

     in_list objs;
     SgStatement *parent;
     do
        {
#if 0
          in_list::iterator startOfCurrent = objs.end();
#endif
          parent = isSgStatement(statement->get_parent());
          //cout << "parent = " << parent << endl;
          ROSE_ASSERT(parent);
          in_list blockObjs = blockObjectsAllocated(parent, statement);
          objs.insert(objs.end(), blockObjs.begin(), blockObjs.end());
#if 0
          switch (parent->variantT())
             {
               case V_SgBasicBlock:
                     {
                       SgBasicBlock *b = isSgBasicBlock(parent);
                       ROSE_ASSERT(b);
                       SgStatementPtrList &stmts = b->get_statements();
                       for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                          {
                            if (*i == statement) break;
                            addStmtVarsIfAny(objs, startOfCurrent, *i);
                          }
                     }
                  break;
               case V_SgForStatement:
                     {
                       SgForStatement *fs = isSgForStatement(parent);
                       SgStatementPtrList &stmts = fs->get_init_stmt();
                       bool done = false;
                       if (!omitInit)
                          {
                            for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i)
                               {
                                 if (*i == statement)
                                    {
                                      done = true;
                                      break;
                                    }
                                 addStmtVarsIfAny(objs, startOfCurrent, *i);
                               }
                          }
                       if (!done)
                          {
                            if (fs->get_test() != statement)
                               {
                                 addStmtVarsIfAny(objs, startOfCurrent, fs->get_test());
                               }
                          }
                     }
                  break;
               default:
                  break;
             }
#endif
          statement = parent;
        } while (!stopCond(parent));
     return objs;
   }
Exemple #2
0
void MintCudaMidend::lowerMinttoCuda(SgSourceFile* file)
{
  //Searches mint pragmas, and performs necessary transformation
  //We also check the mint pragmas syntactically 
  //At this point, we only care parallel regions and for loops
  //But do not process forloops at this point (note that this is bottom-up)
  //We process forloops when we see a parallel region pragma because they are always
  //inside of a parallel region.
  //TODO: Sometimes a forloop is merged with a parallel region. Need to handle these.

  ROSE_ASSERT(file != NULL);

  //replaces all the occurrences of mint parallel with omp parallel 
  replaceMintParallelWithOmpParallel(file);
  replaceMintForWithOmpFor(file);

  //adds the private and first private into private clause explicitly 
  patchUpPrivateVariables(file);  //uses ROSE's
  patchUpFirstprivateVariables(file); //uses ROSE's

  //insert openmp specific headers
  //insertRTLHeaders(file);

  //check if mint pragma declarations are correct
  mintPragmasFrontendProcessing(file);

  //the map has the mapping from the host variables to device variables
  //where we copy the data
  
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(file, V_SgStatement);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();

  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
    {
      SgStatement* node = isSgStatement(*nodeListIterator);
      ROSE_ASSERT(node != NULL);
      switch (node->variantT())
	{
        case V_SgOmpParallelStatement:
          {
	    //first we handle data transfer pragmas
	    MintHostSymToDevInitMap_t hostToDevVars;
	    processDataTransferPragmas(node, hostToDevVars);
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    cout << "  Processing Mint Parallel Statement" << endl << endl;
#endif
	    MintCudaMidend::transOmpParallel(node, hostToDevVars);
            break;
          }
        case V_SgOmpTaskStatement:
          {
            //transOmpTask(node);
            break;
          }
        case V_SgOmpForStatement:
          {
	    //cout << "INFO-mint: Omp For Statement (skipped processing it)" << endl;
	    //LoweringToCuda::transOmpFor(node);
	    //OmpSupport::transOmpFor(node);
            break;
          }
        case V_SgOmpBarrierStatement:
          {
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    cout << "  Processing Omp Barrier Statement" << endl;
#endif
            transOmpBarrierToCudaBarrier(node);
            break;
          }
        case V_SgOmpFlushStatement:
          {
	    cout << "  INFO:Mint: Processing Omp Flush Statement" << endl;
	    transOmpFlushToCudaBarrier(node);
            break;
          }
        case V_SgOmpThreadprivateStatement:
          {
            //transOmpThreadprivate(node);
            break;
          }
	case V_SgOmpTaskwaitStatement:
          {
            //transOmpTaskwait(node);
            break;
          }
        case V_SgOmpSingleStatement:
          {
	    //TODO: we need to check if the loop body becomes a cuda kernel or not. 
	    MintCudaMidend::transOmpSingle(node);
            break;
          }
	case V_SgOmpMasterStatement:
          {
	    //TODO: we need to check if the loop body becomes a cuda kernel or not. 
	    MintCudaMidend::transOmpMaster(node);
            break;
          }
	case V_SgOmpAtomicStatement:
          {
            //transOmpAtomic(node);
            break;
          }
	case V_SgOmpOrderedStatement:
          {
            //transOmpOrdered(node);
            break;
          }
	case V_SgOmpCriticalStatement:
          {
            //transOmpCritical(node);
            break;
          }
        default:
          {
            //This is any other statement in the source code which is not omp pragma
            //cout<< node->unparseToString()<<" at line:"<< (node->get_file_info())->get_line()<<endl;
            // do nothing here    
          }
	}// switch
    } 
#if 0
  //3. Special handling for files with main() 
  // rename main() to user_main()
  SgFunctionDeclaration * mainFunc = findMain(cur_file);
  if (mainFunc) 
    {
      renameMainToUserMain(mainFunc);
    }
#endif

}
Exemple #3
0
void MPI_Code_Generator::lower_xomp (SgSourceFile* file)
{
  ROSE_ASSERT(file != NULL);

  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(file, V_SgStatement);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();
  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
  {
    SgStatement* node = isSgStatement(*nodeListIterator);
    ROSE_ASSERT(node != NULL);
    //debug the order of the statements
    //    cout<<"Debug lower_omp(). stmt:"<<node<<" "<<node->class_name() <<" "<< node->get_file_info()->get_line()<<endl;

    switch (node->variantT())
    {
#if 0
      case V_SgOmpParallelStatement:
        {
          // check if this parallel region is under "omp target"
          SgNode* parent = node->get_parent();
          ROSE_ASSERT (parent != NULL);
          if (isSgBasicBlock(parent)) // skip the padding block in between.
            parent= parent->get_parent();
          if (isSgOmpTargetStatement(parent))
            transOmpTargetParallel(node);
          else  
            transOmpParallel(node);
          break;
        }
      case V_SgOmpForStatement:
      case V_SgOmpDoStatement:
        {
          // check if the loop is part of the combined "omp parallel for" under the "omp target" directive
          // TODO: more robust handling of this logic, not just fixed AST form
          bool is_target_loop = false;
          SgNode* parent = node->get_parent();
          ROSE_ASSERT (parent != NULL);
          // skip a possible BB between omp parallel and omp for, especially when the omp parallel has multiple omp for loops 
          if (isSgBasicBlock(parent))
            parent = parent->get_parent();
          SgNode* grand_parent = parent->get_parent();
          ROSE_ASSERT (grand_parent != NULL);

          if (isSgOmpParallelStatement (parent) && isSgOmpTargetStatement(grand_parent) ) 
            is_target_loop = true;

          if (is_target_loop)
          {
            //            transOmpTargetLoop (node);
            // use round-robin scheduler for larger iteration space and better performance
            transOmpTargetLoop_RoundRobin(node);
          }
          else  
          { 
            transOmpLoop(node);
          }
          break;
        }
#endif
    // transform combined "omp target parallel for", represented as separated three directives: omp target, omp parallel, and omp for     
    case V_SgOmpForStatement:
    {
      SgOmpTargetStatement * omp_target; 
      SgOmpParallelStatement*  omp_parallel;
      if (isCombinedTargetParallelFor (isSgOmpForStatement(node),&omp_target, &omp_parallel )) 
      {
        transOmpTargetParallelLoop (isSgOmpForStatement(node));
      }
      break;
    }
    case V_SgOmpTargetStatement:
        {
          SgOmpTargetStatement* t_stmt = isSgOmpTargetStatement(node);
          ROSE_ASSERT (t_stmt != NULL);
          SgStatement* body_stmt = t_stmt->get_body();
          SgBasicBlock * body_block = isSgBasicBlock (body_stmt);
//          transOmpTarget(node);
          if (isMPIAllBegin (t_stmt))
          {
            // move all body statements to be after omp target
            if (body_block != NULL)
            {
              stripOffBasicBlock (body_block, t_stmt);
            }
            else
            {
              //TODO: ideally, the body_stmt should be normalized to be a BB even it is only a single statement
              removeStatement (body_stmt);
              insertStatementAfter (t_stmt, body_stmt, false);
            }
            // remove the pragma stmt after the translation
            removeStatement (t_stmt);
          }
          else if (isMPIMasterBegin (t_stmt))
          {
            transMPIDeviceMaster (t_stmt);
          }
          else
          {
            // other target directive with followed omp parallel for will be handled when parallel for is translated
            // cerr<<"Error. Unhandled target directive:" <<t_stmt->unparseToString()<<endl;
            //ROSE_ASSERT (false);
          }
          break;
        }
     default:
        {
          // do nothing here    
        }
    }// switch

  } // end for 

}
Exemple #4
0
void MintCudaMidend::processLoopsInParallelRegion(SgNode* parallelRegionNode, 
						 MintHostSymToDevInitMap_t hostToDevVars,
						 ASTtools::VarSymSet_t& deviceSyms, 
						 MintSymSizesMap_t& trfSizes,
						 std::set<SgInitializedName*>& readOnlyVars,
						 const SgVariableSymbol* dev_struct)
{
  Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(parallelRegionNode, V_SgStatement);
  Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin();

  for ( ;nodeListIterator !=nodeList.rend();  ++nodeListIterator)
    {
      SgStatement* node = isSgStatement(*nodeListIterator);
   
      ROSE_ASSERT(node != NULL);
      switch (node->variantT())
        {
        case V_SgOmpForStatement:
          {
#ifdef VERBOSE_2
	    cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
            cout << "  Processing Omp For Statement" << endl << endl;
#endif
	    //DataTransferSizes::findTransferSizes(node, trfSizes);
	
	    bool isBoundaryCond = LoweringToCuda::isBoundaryConditionLoop(node);
	    
	    SgFunctionDeclaration* kernel;
	
	    MintForClauses_t clauseList; 

	    //kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, readOnlyVars,clauseList, dev_struct) ;  	    
	    kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, clauseList, dev_struct) ;  	    

	    //swap anyways // x swapping is buggy, need to fix that before allowing x as well
	    if(clauseList.chunksize.x == 1 && ( clauseList.chunksize.z != 1 || clauseList.chunksize.y != 1 ))
	      {
		//if(MintOptions::GetInstance()->isSwapOpt())
		CudaOptimizer::swapLoopAndIf(kernel, clauseList);
	      }
	    if (!isBoundaryCond && MintOptions::GetInstance()->optimize())
	      //if (MintOptions::GetInstance()->optimize())
	      {
		cout << "\n\n  INFO:Mint: Optimization is ON. Optimizing ...\n\n" ;

		CudaOptimizer::optimize(kernel, clauseList);
	      } 
	    //  MintTools::printAllStatements(isSgNode(kernel));
	    //MintArrayInterface::linearizeArrays(kernel);
	    break;
          }
	default:
	  {
	    //cout << "  INFO:Mint: @ Line " << node->get_file_info()->get_line()  << endl;
	    //cout << "  Currently we only handle for loops" << endl << endl;
	    
	    //do nothing
	    //currently we only handle for loops
	    break;
	  }
	}
    }
  
  
  for (ASTtools::VarSymSet_t::const_iterator i = deviceSyms.begin (); i!= deviceSyms.end (); ++i)
    {     
      SgVariableSymbol* sym= const_cast<SgVariableSymbol*> (*i);

      SgInitializedName* name = sym->get_declaration();
      SgType* type = name->get_type();
     
      if(isSgArrayType(type) || isSgPointerType(type)){
	
	//Check if is of the fields of the struct
	if(hostToDevVars.find(sym) == hostToDevVars.end())
	  {
	    string name_str = name->get_name().str();
	    
	    cerr << "  ERR:Mint: Ooops! Did you forget to insert a copy pragma for the variable ("<< name_str << ") ?"<< endl;
	    cerr << "  ERR:Mint: Please insert the copy pragma and compile again "<< endl;
	    cerr << "  INFO:Mint: Note that copy pragmas should appear right before and after a parallel region" << endl;
	    ROSE_ABORT();
	  }
      }
      }
}