2023-09-14 19:43:13 +03:00
# include "../Utils/leak_detector.h"
# include <cstdio>
# include <cstdlib>
# include <cstring>
# include <cstdint>
# include <assert.h>
# include <string>
# include <vector>
# include <map>
# include <set>
# include "dvm.h"
# include "../Distribution/GraphCSR.h"
# include "../Distribution/Arrays.h"
# include "../Distribution/Distribution.h"
# include "../Distribution/DvmhDirective_func.h"
# include "../GraphLoop/graph_loops_func.h"
# include "../GraphCall/graph_calls_func.h"
# include "../Utils/errors.h"
# include "../LoopAnalyzer/loop_analyzer.h"
# include "directive_parser.h"
# include "../Utils/SgUtils.h"
# include "../Sapfor.h"
# include "directive_creator.h"
# include "insert_directive.h"
using std : : string ;
using std : : wstring ;
using std : : vector ;
using std : : map ;
using std : : set ;
using std : : pair ;
using std : : tuple ;
using std : : make_pair ;
using std : : make_tuple ;
static const string dvmhModuleName = " dvmh_template_mod " ;
2024-06-19 18:08:27 +03:00
extern int sharedMemoryParallelization ;
2024-03-24 21:24:32 +03:00
2023-09-14 19:43:13 +03:00
//the size of vector indiceates type of DVM_DIR
SgStatement * createStatFromExprs ( const vector < Expression * > & exprs )
{
SgStatement * result = NULL ;
if ( exprs . size ( ) = = 3 )
result = new SgStatement ( DVM_PARALLEL_ON_DIR , NULL , NULL , NULL , NULL , NULL ) ;
else if ( exprs . size ( ) = = 4 )
result = new SgStatement ( DVM_REDISTRIBUTE_DIR , NULL , NULL , NULL , NULL , NULL ) ;
else if ( exprs . size ( ) = = 5 )
result = new SgStatement ( DVM_REALIGN_DIR , NULL , NULL , NULL , NULL , NULL ) ;
else if ( exprs . size ( ) = = 6 )
result = new SgStatement ( DVM_DISTRIBUTE_DIR , NULL , NULL , NULL , NULL , NULL ) ;
else if ( exprs . size ( ) = = 7 )
result = new SgStatement ( HPF_TEMPLATE_STAT , NULL , NULL , NULL , NULL , NULL ) ;
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
for ( int i = 0 ; i < 3 ; + + i )
if ( exprs [ i ] )
result - > setExpression ( i , * exprs [ i ] ) ;
return result ;
}
static void removeDoubleRealign ( vector < vector < Expression * > > & realigns )
{
if ( realigns . size ( ) < 2 )
return ;
vector < bool > save ;
for ( int z = 0 ; z < realigns . size ( ) ; + + z )
save . push_back ( true ) ;
bool changed = false ;
for ( int z = 1 ; z < realigns . size ( ) ; + + z )
{
for ( int zp = 0 ; zp < z ; + + zp )
{
if ( ! save [ zp ] )
continue ;
auto prev = string ( realigns [ zp ] [ 0 ] - > unparse ( ) ) ;
auto curr = string ( realigns [ z ] [ 0 ] - > unparse ( ) ) ;
if ( prev = = curr )
{
save [ zp ] = false ;
changed = true ;
}
else
{
set < string > listNext ;
SgExpression * ex = realigns [ z ] [ 0 ] ;
while ( ex )
{
listNext . insert ( ex - > lhs ( ) - > symbol ( ) - > identifier ( ) ) ;
ex = ex - > rhs ( ) ;
}
ex = realigns [ zp ] [ 0 ] ;
vector < SgExpression * > newExp ;
while ( ex )
{
if ( listNext . find ( ex - > lhs ( ) - > symbol ( ) - > identifier ( ) ) = = listNext . end ( ) )
newExp . push_back ( ex - > lhs ( ) ) ;
ex = ex - > rhs ( ) ;
}
if ( newExp . size ( ) )
realigns [ zp ] [ 0 ] = new Expression ( makeExprList ( newExp ) ) ;
else
{
save [ zp ] = false ;
changed = true ;
}
}
}
}
if ( ! changed )
return ;
vector < vector < Expression * > > newVal ;
for ( int z = 0 ; z < realigns . size ( ) ; + + z )
if ( save [ z ] )
newVal . push_back ( realigns [ z ] ) ;
realigns = newVal ;
}
static void filterInsertMap ( map < int , vector < vector < Expression * > > > & toInsertMap )
{
for ( auto it = toInsertMap . begin ( ) ; it ! = toInsertMap . end ( ) ; + + it )
{
vector < vector < Expression * > > newVal ;
vector < vector < Expression * > > realign , redis ;
for ( int z = 0 ; z < it - > second . size ( ) ; + + z )
{
if ( it - > second [ z ] . size ( ) = = 4 )
redis . push_back ( it - > second [ z ] ) ;
else if ( it - > second [ z ] . size ( ) = = 5 )
realign . push_back ( it - > second [ z ] ) ;
else
newVal . push_back ( it - > second [ z ] ) ;
}
//removeDoubleRedistribute
//TODO: deprecated?
for ( auto & elem : redis )
newVal . push_back ( elem ) ;
//removeDoubleRealign
removeDoubleRealign ( realign ) ;
for ( auto & elem : realign )
newVal . push_back ( elem ) ;
//sort by type
map < int , vector < vector < Expression * > > > toSort ;
for ( auto & elem : newVal )
toSort [ elem . size ( ) ] . push_back ( elem ) ;
newVal . clear ( ) ;
for ( auto itR = toSort . rbegin ( ) ; itR ! = toSort . rend ( ) ; itR + + )
{
for ( auto & elem : itR - > second )
newVal . push_back ( elem ) ;
}
it - > second = newVal ;
}
}
static void correctKeyLine ( SgFile * file , map < int , vector < vector < Expression * > > > & toInsertMap )
{
set < int > lines ;
vector < int > lines_v ;
for ( SgStatement * st = file - > firstStatement ( ) ; st ; st = st - > lexNext ( ) )
{
if ( st - > lineNumber ( ) > 0 | | st - > lineNumber ( ) < 0 & & st - > variant ( ) = = FOR_NODE )
lines . insert ( st - > lineNumber ( ) ) ;
if ( st - > variant ( ) < 0 )
st = st - > lastNodeOfStmt ( ) ;
}
for ( auto & l : lines )
lines_v . push_back ( l ) ;
map < int , vector < vector < Expression * > > > newMap ;
for ( auto & elem : toInsertMap )
{
if ( std : : find ( lines_v . begin ( ) , lines_v . end ( ) , elem . first ) ! = lines_v . end ( ) )
newMap [ elem . first ] = elem . second ;
else
{
int lineNext = - 1 ;
for ( int z = 0 ; z < lines_v . size ( ) ; + + z )
{
if ( lines_v [ z ] > elem . first )
{
lineNext = lines_v [ z ] ;
break ;
}
}
if ( lineNext = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
newMap [ lineNext ] = elem . second ;
}
}
toInsertMap = newMap ;
}
void removeStatementsFromAllproject ( const set < int > & variants )
{
for ( int z = 0 ; z < CurrentProject - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & CurrentProject - > file ( z ) ;
SgStatement * stF = file - > firstStatement ( ) ;
vector < SgStatement * > toDel ;
for ( SgStatement * st = stF ; st ; st = st - > lexNext ( ) )
{
const int var = st - > variant ( ) ;
bool templateMod = false ;
if ( var = = MODULE_STMT )
{
string ident = st - > symbol ( ) - > identifier ( ) ;
convertToLower ( ident ) ;
if ( ident = = dvmhModuleName )
templateMod = true ;
}
bool useMod = false ;
if ( var = = USE_STMT & & st - > symbol ( ) - > identifier ( ) = = dvmhModuleName )
useMod = true ;
if ( variants . find ( var ) ! = variants . end ( ) | | templateMod | | useMod )
toDel . push_back ( st ) ;
if ( var = = MODULE_STMT & & templateMod )
st = st - > lastNodeOfStmt ( ) ;
}
for ( int k = 0 ; k < toDel . size ( ) ; + + k )
{
//move comment to next statement
if ( toDel [ k ] - > comments ( ) )
{
char * comms = toDel [ k ] - > comments ( ) ;
string comments ( comms ) ;
toDel [ k ] - > delComments ( ) ;
SgStatement * next = toDel [ k ] - > lexNext ( ) ;
if ( next )
next - > addComment ( comments . c_str ( ) ) ;
}
toDel [ k ] - > deleteStmt ( ) ;
}
}
}
// TODO: optimize REDISTR dirs with CFG
void insertDirectiveToFile ( SgFile * file , const char * fin_name , const vector < Directive * > & toInsert ,
const bool extractDir , vector < Messages > & messagesForFile )
{
map < int , vector < vector < Expression * > > > toInsertMap ;
for ( int i = 0 ; i < toInsert . size ( ) ; + + i )
{
auto it = toInsertMap . find ( toInsert [ i ] - > line ) ;
if ( it = = toInsertMap . end ( ) )
{
vector < vector < Expression * > > tmp ;
tmp . push_back ( ( ( CreatedDirective * ) toInsert [ i ] ) - > sageData ) ;
toInsertMap . insert ( it , make_pair ( toInsert [ i ] - > line , tmp ) ) ;
}
else
it - > second . push_back ( ( ( CreatedDirective * ) toInsert [ i ] ) - > sageData ) ;
}
filterInsertMap ( toInsertMap ) ;
correctKeyLine ( file , toInsertMap ) ;
vector < SgStatement * > toDel ;
vector < SgStatement * > modulesAndFuncs ;
getModulesAndFunctions ( file , modulesAndFuncs ) ;
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
SgStatement * st = modulesAndFuncs [ i ] ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
if ( extractDir & & st - > variant ( ) = = MODULE_STMT )
{
if ( st - > symbol ( ) - > identifier ( ) = = dvmhModuleName )
{
st - > deleteStmt ( ) ;
continue ;
}
}
int numSt = 0 ;
do
{
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
if ( numSt ! = 0 )
st = st - > lexNext ( ) ;
if ( st = = NULL )
{
messagesForFile . push_back ( Messages ( ERROR , 1 , R128 , L " internal error in analysis, parallel directives will not be generated for this file! " , 3008 ) ) ;
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( ! strcmp ( st - > fileName ( ) , fin_name ) )
{
auto it = toInsertMap . find ( st - > lineNumber ( ) ) ;
if ( it ! = toInsertMap . end ( ) )
{
if ( extractDir = = false )
{
for ( int i1 = 0 ; i1 < it - > second . size ( ) ; + + i1 )
{
SgStatement * dirToInsert = createStatFromExprs ( ( it - > second [ i1 ] ) ) ;
const int varSt = st - > variant ( ) ;
if ( varSt = = PROC_HEDR | | varSt = = PROG_HEDR | | varSt = = FUNC_HEDR | | varSt = = MODULE_STMT )
st - > insertStmtAfter ( * dirToInsert , * st ) ;
else
st - > insertStmtBefore ( * dirToInsert , * ( st - > controlParent ( ) ) ) ;
if ( st - > comments ( ) )
{
char * comms = st - > comments ( ) ;
string comments ( comms ) ;
st - > delComments ( ) ;
st - > lexPrev ( ) - > addComment ( comments . c_str ( ) ) ;
}
}
}
toInsertMap . erase ( it ) ;
}
}
if ( extractDir )
{
const int var = st - > variant ( ) ;
if ( var = = DVM_PARALLEL_ON_DIR | |
var = = DVM_REDISTRIBUTE_DIR | |
var = = DVM_REALIGN_DIR | |
var = = DVM_REMOTE_ACCESS_DIR | |
var = = DVM_SHADOW_DIR | |
var = = DVM_INHERIT_DIR | |
var = = DVM_DYNAMIC_DIR | |
( var = = USE_STMT & & st - > lineNumber ( ) < 0 ) | |
var = = HPF_TEMPLATE_STAT | |
var = = DVM_ALIGN_DIR | |
var = = DVM_DISTRIBUTE_DIR | |
var = = DVM_VAR_DECL | |
var = = ACC_REGION_DIR | | var = = ACC_END_REGION_DIR | |
var = = ACC_ACTUAL_DIR | | var = = ACC_GET_ACTUAL_DIR )
{
toDel . push_back ( st ) ;
//move comment to next statement
if ( st - > comments ( ) )
{
char * comms = st - > comments ( ) ;
string comments ( comms ) ;
st - > delComments ( ) ;
SgStatement * next = st - > lexNext ( ) ;
if ( next )
next - > addComment ( comments . c_str ( ) ) ;
}
}
}
numSt + + ;
} while ( st ! = lastNode ) ;
if ( extractDir )
{
for ( int k = 0 ; k < toDel . size ( ) ; + + k )
{
if ( toDel [ k ] - > lineNumber ( ) > 0 ) // user directives, skip
; // printInternalError(convertFileName(__FILE__).c_str(), __LINE__);
else
toDel [ k ] - > deleteStmt ( ) ;
}
}
}
}
static void moveComment ( SgStatement * elem , const string addNew = " " )
{
string comms = " " ;
if ( elem - > comments ( ) )
comms = elem - > comments ( ) ;
comms + = addNew ;
if ( comms ! = " " )
{
auto toAddComm = elem ;
while ( toAddComm )
{
toAddComm = toAddComm - > lexNext ( ) ;
if ( toAddComm & & ! isDVM_stat ( toAddComm ) )
break ;
}
if ( toAddComm = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
string comms2 = " " ;
if ( toAddComm - > comments ( ) )
comms2 = toAddComm - > comments ( ) ;
comms + = comms2 ;
if ( comms ! = " " )
toAddComm - > setComments ( comms . c_str ( ) ) ;
}
}
static void replaceComment ( string & dir , const char * firstChar )
{
const string templ = firstChar + string ( " DVM$ " ) ;
size_t offset = 0 ;
for ( ; ; )
{
offset = dir . find ( templ , offset ) ;
if ( offset = = string : : npos )
break ;
else
{
dir . insert ( offset + 1 , " " ) ;
offset + = 6 ;
}
}
}
void removeDvmDirectives ( SgFile * file , const bool toComment )
{
vector < SgStatement * > toDel ;
vector < SgStatement * > toTotalDel ;
const string currFile = file - > filename ( ) ;
vector < SgStatement * > toProcess ;
getModulesAndFunctions ( file , toProcess ) ;
for ( int i = 0 ; i < toProcess . size ( ) ; + + i )
{
SgStatement * st = toProcess [ i ] ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
while ( st ! = lastNode )
{
if ( st = = NULL )
{
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
const int var = st - > variant ( ) ;
if ( isDVM_stat ( st ) )
if ( st - > fileName ( ) = = currFile )
toDel . push_back ( st ) ;
if ( ( var = = USE_STMT | | var = = MODULE_STMT ) & & st - > symbol ( ) - > identifier ( ) = = string ( " dvmh_template_mod " ) )
toTotalDel . push_back ( st ) ;
st = st - > lexNext ( ) ;
}
}
if ( toComment )
{
for ( auto & elem : toDel )
{
moveComment ( elem ) ;
elem - > delComments ( ) ;
char * tmp = elem - > unparse ( ) ;
if ( tmp = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
string dir ( tmp ) ;
convertToUpper ( dir ) ;
replaceComment ( dir , " ! " ) ;
replaceComment ( dir , " C " ) ;
moveComment ( elem , dir ) ;
elem - > deleteStmt ( ) ;
}
}
else
{
for ( auto & elem : toDel )
{
moveComment ( elem ) ;
elem - > deleteStmt ( ) ;
}
}
for ( auto & elem : toTotalDel )
{
moveComment ( elem ) ;
elem - > deleteStmt ( ) ;
}
}
static inline pair < string , SgExpression * > genBoundsOfDim ( const pair < int , int > & intBounds , const pair < Expression * , Expression * > & exprBounds )
{
if ( intBounds . first > intBounds . second )
{
if ( exprBounds . first = = NULL | | exprBounds . second = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
else
{
return make_pair ( string ( exprBounds . first - > unparse ( ) ) + " : " + string ( exprBounds . second - > unparse ( ) ) ,
new SgExpression ( DDOT , exprBounds . first , exprBounds . second , NULL ) ) ;
}
}
else
return make_pair ( std : : to_string ( intBounds . first ) + " : " + std : : to_string ( intBounds . second ) ,
new SgExpression ( DDOT , new SgValueExp ( intBounds . first ) , new SgValueExp ( intBounds . second ) , NULL ) ) ;
}
static inline pair < string , SgStatement * > genTemplateDelc ( DIST : : Array * templ , const string & name , SgFile * file , SgStatement * module = NULL , bool isMain = false )
{
string templDecl = ( module = = NULL ) ? " !DVM$ TEMPLATE, COMMON :: " : " !DVM$ TEMPLATE " ;
SgStatement * templDeclSt = NULL ;
if ( module = = NULL )
templDeclSt = new SgStatement ( DVM_VAR_DECL ) ;
else
templDeclSt = new SgStatement ( HPF_TEMPLATE_STAT ) ;
if ( module & & templ - > IsTemplate ( ) & & ! templ - > IsLoopArray ( ) )
templ - > ChangeLocation ( DIST : : l_MODULE , module - > symbol ( ) - > identifier ( ) ) ;
const vector < pair < int , int > > & sizes = templ - > GetSizes ( ) ;
const auto & sizesExpr = templ - > GetSizesExpr ( ) ;
for ( auto & size : sizes )
{
if ( templ - > IsLoopArray ( ) )
{
// TODO: move gen sizes to TEMPLATE CREATE directive immediately before parallel loop
bool ok = true ;
for ( auto & elem : sizesExpr )
if ( elem . first . first = = NULL | | elem . second . first = = NULL )
ok = false ;
if ( size . first > size . second & & module = = NULL & & ! ok )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
else
{
if ( size . first > size . second )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
SgExprListExp * listDim = new SgExprListExp ( ) ;
templDecl + = name + " ( " ;
for ( int z = 0 ; z < sizes . size ( ) ; + + z )
{
auto bounds = genBoundsOfDim ( sizes [ z ] , make_pair ( sizesExpr [ z ] . first . first , sizesExpr [ z ] . second . first ) ) ;
templDecl + = bounds . first ;
if ( z = = 0 )
listDim - > setLhs ( bounds . second ) ;
else
listDim - > append ( * bounds . second ) ;
if ( z ! = sizes . size ( ) - 1 )
templDecl + = " , " ;
}
templDecl + = " ) \n " ;
if ( module ! = NULL )
templDeclSt - > setExpression ( 0 , new SgArrayRefExp ( * findSymbolOrCreate ( file , name , new SgArrayType ( * SgTypeInt ( ) ) ) , * listDim ) ) ;
else
templDeclSt - > setExpression ( 0 , new SgExpression ( EXPR_LIST , new SgArrayRefExp ( * findSymbolOrCreate ( file , name , new SgArrayType ( * SgTypeInt ( ) ) ) , * listDim ) , NULL , NULL ) ) ;
if ( module = = NULL )
templDeclSt - > setExpression ( 2 , new SgExpression ( EXPR_LIST , new SgExpression ( TEMPLATE_OP ) , new SgExpression ( EXPR_LIST , new SgExpression ( COMMON_OP ) , NULL , NULL ) , NULL ) ) ;
return make_pair ( templDecl , templDeclSt ) ;
}
static inline pair < string , SgStatement * >
genTemplateDistr ( DIST : : Array * array , const string & name , const vector < string > & distrRules , const vector < vector < dist > > & distrRulesSt ,
const uint64_t regionId , const int templIdx , bool isMain , SgFile * file )
{
auto newOrder = array - > GetNewTemplateDimsOrder ( ) ;
//TODO:!!!
//"!DVM$ DISTRIBUTE :: " + templ->GetShortName() + "\n";
SgExpression * ex1 = new SgVarRefExp ( * findSymbolOrCreate ( file , name ) ) ;
SgExprListExp * ex2 = new SgExprListExp ( ) ;
for ( int z = 0 ; z < distrRulesSt [ templIdx ] . size ( ) ; + + z )
{
string val = " " ;
if ( newOrder . size ( ) = = 0 )
{
if ( distrRulesSt [ templIdx ] [ z ] = = dist : : BLOCK )
val = " BLOCK " ;
else
val = " * " ;
}
else
{
if ( distrRulesSt [ templIdx ] [ newOrder [ z ] ] = = dist : : BLOCK )
val = " BLOCK " ;
else
val = " * " ;
}
if ( z = = 0 )
ex2 - > setLhs ( new SgKeywordValExp ( val . c_str ( ) ) ) ;
else
ex2 - > append ( * new SgKeywordValExp ( val . c_str ( ) ) ) ;
}
SgStatement * distrSt = new SgStatement ( DVM_DISTRIBUTE_DIR , NULL , NULL , ex1 , ex2 , NULL ) ;
return make_pair ( " !DVM$ DISTRIBUTE " + distrRules [ templIdx ] + " \n " , distrSt ) ;
}
static pair < string , SgStatement * > genDynamicDecl ( DIST : : Array * templ , SgFile * file )
{
auto allClones = templ - > GetAllClones ( ) ;
string templDyn = " !DVM$ DYNAMIC " + templ - > GetShortName ( ) ;
for ( auto & elem : allClones )
templDyn + = " , " + elem . second ;
templDyn + = " \n " ;
SgStatement * templDynSt = NULL ;
if ( allClones . size ( ) = = 0 )
templDynSt = new SgStatement ( DVM_DYNAMIC_DIR , NULL , NULL , new SgVarRefExp ( * findSymbolOrCreate ( file , templ - > GetShortName ( ) ) ) , NULL , NULL ) ;
else
{
vector < SgExpression * > list ;
list . push_back ( new SgVarRefExp ( * findSymbolOrCreate ( file , templ - > GetShortName ( ) ) ) ) ;
for ( auto & elem : allClones )
list . push_back ( new SgVarRefExp ( * findSymbolOrCreate ( file , elem . second ) ) ) ;
templDynSt = new SgStatement ( DVM_DYNAMIC_DIR , NULL , NULL , makeExprList ( list ) , NULL , NULL ) ;
}
return make_pair ( templDyn , templDynSt ) ;
}
static inline int findTeplatePosition ( const DIST : : Array * templ , const DataDirective & dataDir )
{
int templIdx = - 1 ;
const string templName = templ - > GetShortName ( ) ;
for ( int z = 0 ; z < dataDir . distrRules . size ( ) ; + + z )
{
if ( dataDir . distrRules [ z ] . first - > GetShortName ( ) = = templName )
{
templIdx = z ;
break ;
}
}
if ( templIdx = = - 1 )
{
__spf_print ( 1 , " can not find template position ['%s'] \n " , templName . c_str ( ) ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
return templIdx ;
}
static inline DIST : : Array * findLinkWithTemplate ( DIST : : Array * alignArray , const DIST : : Arrays < int > & allArrays ,
DIST : : GraphCSR < int , double , attrType > & reducedG , const uint64_t regionId )
{
DIST : : Array * templ = NULL ;
vector < tuple < DIST : : Array * , int , pair < int , int > > > links ;
reducedG . GetAlignRuleWithTemplate ( alignArray , allArrays , links , regionId ) ;
for ( int i = 0 ; i < links . size ( ) ; + + i )
{
templ = std : : get < 0 > ( links [ i ] ) ;
if ( templ )
break ;
}
return templ ;
}
static string createFullTemplateDir ( const tuple < string , string , string > & templDir )
{
string fullDir = " " ;
if ( ! out_free_form )
{
fullDir + = splitDirectiveFull ( std : : get < 0 > ( templDir ) ) ;
fullDir + = splitDirectiveFull ( std : : get < 1 > ( templDir ) ) ;
fullDir + = splitDirectiveFull ( std : : get < 2 > ( templDir ) ) ;
}
else
fullDir + = std : : get < 0 > ( templDir ) + std : : get < 1 > ( templDir ) + std : : get < 2 > ( templDir ) ;
return fullDir ;
}
struct templateDir
{
templateDir ( ) { isTemplateInModule = false ; }
pair < string , vector < SgStatement * > > templDecl ;
pair < string , vector < SgStatement * > > templDist ;
pair < string , SgStatement * > templDyn ;
bool isTemplateInModule ;
} ;
static pair < templateDir , string >
getNewTemplateDirective ( DIST : : Array * alignArray , const DIST : : Arrays < int > & allArrays ,
DIST : : GraphCSR < int , double , attrType > & reducedG ,
const DataDirective & dataDir , const vector < string > & distrRules ,
const vector < vector < dist > > & distrRulesSt ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
const uint64_t regionId , SgStatement * module , bool isMain , SgFile * file ,
vector < Messages > & messagesForFile )
{
DIST : : Array * templ = findLinkWithTemplate ( alignArray , allArrays , reducedG , regionId ) ;
bool templDynSt = false ;
string lastReturn = " " ;
//checkNull(templ, convertFileName(__FILE__).c_str(), __LINE__);
if ( templ = = NULL )
{
set < DIST : : Array * > realArrayRefs ;
getRealArrayRefs ( alignArray , alignArray , realArrayRefs , arrayLinksByFuncCalls ) ;
vector < DIST : : Array * > templates ;
for ( auto & array : realArrayRefs )
templates . push_back ( findLinkWithTemplate ( array , allArrays , reducedG , regionId ) ) ;
if ( templates . size ( ) = = 0 )
{
__spf_print ( 1 , " can not find templates \n " ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
else if ( templates . size ( ) = = 1 )
templ = templates [ 0 ] ;
else
{
templ = templates [ 0 ] ;
bool isErr = false ;
for ( auto & t : templates )
{
if ( t ! = templ )
{
isErr = true ;
__spf_print ( 1 , " find more then one template: %s and %s, align array is %s \n " , t - > GetShortName ( ) . c_str ( ) , templ - > GetShortName ( ) . c_str ( ) , alignArray - > GetShortName ( ) . c_str ( ) ) ;
}
}
if ( isErr )
{
auto allDecl = alignArray - > GetDeclInfo ( ) ;
for ( auto & decl : allDecl )
{
std : : wstring bufE , bufR ;
__spf_printToLongBuf ( bufE , L " Can not find align rules for array '%s' " , to_wstring ( alignArray - > GetShortName ( ) ) . c_str ( ) ) ;
__spf_printToLongBuf ( bufR , R171 , to_wstring ( alignArray - > GetShortName ( ) ) . c_str ( ) ) ;
messagesForFile . push_back ( Messages ( ERROR , decl . second , bufR , bufE , 3020 ) ) ;
}
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
lastReturn = " !DVM$ INHERIT \n " ;
}
else
lastReturn = templ - > GetShortName ( ) ;
auto allClones = templ - > GetAllClones ( ) ;
templateDir retDir ;
int templIdx = findTeplatePosition ( templ , dataDir ) ;
auto templDecl = genTemplateDelc ( templ , templ - > GetShortName ( ) , file , module , isMain ) ;
retDir . templDecl . first = templDecl . first ;
retDir . templDecl . second . push_back ( templDecl . second ) ;
for ( auto & elem : allClones )
{
auto templDecl = genTemplateDelc ( templ , elem . second , file , module , isMain ) ;
retDir . templDecl . first + = templDecl . first ;
retDir . templDecl . second . push_back ( templDecl . second ) ;
}
auto templDist = genTemplateDistr ( templ , templ - > GetShortName ( ) , distrRules , distrRulesSt , regionId , templIdx , isMain | | module ! = NULL , file ) ;
retDir . templDist . first = templDist . first ;
retDir . templDist . second . push_back ( templDist . second ) ;
if ( templ - > GetLocation ( ) . first = = DIST : : l_MODULE )
retDir . isTemplateInModule = true ;
for ( auto & elem : allClones )
{
vector < vector < dist > > tmpRuleSt = { elem . first } ;
string strRule = elem . second + " ( " ;
for ( int z = 0 ; z < elem . first . size ( ) ; + + z )
{
if ( z ! = 0 )
strRule + = " , " ;
if ( elem . first [ z ] = = BLOCK )
strRule + = " BLOCK " ;
else if ( elem . first [ z ] = = NONE )
strRule + = " * " ;
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
strRule + = " ) " ;
vector < string > tmpStrRule = { strRule } ;
auto templDist = genTemplateDistr ( templ , elem . second , tmpStrRule , tmpRuleSt , regionId , 0 , isMain | | module ! = NULL , file ) ;
retDir . templDist . first + = templDist . first ;
retDir . templDist . second . push_back ( templDist . second ) ;
}
retDir . templDyn = genDynamicDecl ( templ , file ) ;
return make_pair ( retDir , lastReturn ) ;
}
2025-02-10 17:16:15 +03:00
static pair < string , string > getModuleRename ( const set < SgStatement * > & allocatableStmts , const DIST : : Array * array )
2023-09-14 19:43:13 +03:00
{
2025-02-10 17:16:15 +03:00
if ( array - > GetLocation ( ) . first = = DIST : : l_MODULE )
{
set < string > arrayNames ;
for ( auto & alloc : allocatableStmts )
if ( alloc - > variant ( ) = = ALLOCATE_STMT )
2025-02-18 13:45:20 +03:00
arrayNames . insert ( array - > GetNameInLocation ( alloc ) ) ;
2025-02-10 17:16:15 +03:00
if ( arrayNames . size ( ) > 1 | | arrayNames . size ( ) = = 0 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return make_pair ( array - > GetShortName ( ) , * arrayNames . begin ( ) ) ;
}
else
return make_pair ( " " , " " ) ;
2023-09-14 19:43:13 +03:00
}
static pair < DIST : : Array * , string >
getNewDirective ( const string & fullArrayName ,
const vector < string > & distrRules ,
const vector < string > & alignRules ,
const DataDirective & dataDir ,
2025-02-10 17:16:15 +03:00
const set < SgStatement * > & allocatableStmts )
2023-09-14 19:43:13 +03:00
{
string out = " " ;
DIST : : Array * outA = NULL ;
for ( int i = 0 ; i < dataDir . distrRules . size ( ) ; + + i )
{
if ( dataDir . distrRules [ i ] . first - > GetName ( ) = = fullArrayName )
{
out + = " !DVM$ DISTRIBUTE " + distrRules [ i ] + " \n " ;
if ( ! out_free_form )
out = splitDirective ( out ) ;
return make_pair ( dataDir . distrRules [ i ] . first , out ) ;
}
}
for ( int i = 0 ; i < dataDir . alignRules . size ( ) ; + + i )
{
if ( dataDir . alignRules [ i ] . alignArray - > GetName ( ) = = fullArrayName )
{
string rule = alignRules [ i ] ;
2025-02-10 17:16:15 +03:00
if ( allocatableStmts . size ( ) )
2023-09-14 19:43:13 +03:00
{
auto it = rule . find ( " ALIGN " ) ;
while ( it ! = string : : npos )
{
rule = rule . replace ( it , 5 , " REALIGN " ) ;
it = rule . find ( " ALIGN " , it + 7 ) ;
}
2025-02-10 17:16:15 +03:00
auto renamePair = getModuleRename ( allocatableStmts , dataDir . alignRules [ i ] . alignArray ) ;
2023-09-14 19:43:13 +03:00
if ( renamePair . first ! = " " )
{
it = rule . find ( renamePair . first ) ;
if ( it ! = string : : npos )
if ( rule [ it + renamePair . first . size ( ) ] = = ' ( ' & & rule [ it - 1 ] = = ' ' )
rule = rule . replace ( it , renamePair . first . size ( ) , renamePair . second ) ;
}
}
out + = " !DVM$ " + rule + " \n " ;
if ( ! out_free_form )
out = splitDirective ( out ) ;
return make_pair ( dataDir . alignRules [ i ] . alignArray , out ) ;
}
}
return make_pair ( outA , out ) ;
}
static SgStatement * firstExec ( SgStatement * in , const string & currF )
{
while ( in )
{
if ( isSgExecutableStatement ( in ) & & ! isSPF_stat ( in ) & & in - > fileName ( ) = = currF )
return in ;
in = in - > lexNext ( ) ;
}
return in ;
}
void insertLoopTempalteDeclaration ( SgFile * file , const DataDirective & dataDir ,
const vector < string > & distrRules , const vector < vector < dist > > & distrRulesSt ,
const DIST : : Arrays < int > & allArrays ,
const bool extractDir , const uint64_t regionId )
{
vector < SgStatement * > modulesAndFuncs ;
getModulesAndFunctions ( file , modulesAndFuncs ) ;
const set < DIST : : Array * > & arrays = allArrays . GetArrays ( ) ;
set < DIST : : Array * > loopArrays ;
for ( auto & array : arrays )
if ( array - > IsTemplate ( ) & & array - > IsLoopArray ( ) )
loopArrays . insert ( array ) ;
if ( loopArrays . size ( ) )
{
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
SgStatement * st = modulesAndFuncs [ i ] ;
string name = " " ;
if ( st - > variant ( ) = = PROG_HEDR | | ( st - > variant ( ) = = FUNC_HEDR ) )
name = ( ( SgFuncHedrStmt * ) st ) - > name ( ) . identifier ( ) ;
else if ( st - > variant ( ) = = PROC_HEDR )
name = ( ( SgProcHedrStmt * ) st ) - > name ( ) . identifier ( ) ;
if ( name = = " " )
continue ;
for ( auto & arrayPair : sortArraysByName ( loopArrays ) )
{
DIST : : Array * array = arrayPair . second ;
const auto & location = array - > GetLocation ( ) ;
if ( location . second = = name )
{
int templIdx = findTeplatePosition ( array , dataDir ) ;
string tmp = distrRules [ templIdx ] ;
convertToLower ( tmp ) ;
if ( tmp . find ( " block " ) = = string : : npos )
continue ;
auto templDecl = genTemplateDelc ( array , array - > GetShortName ( ) , file , ( SgStatement * ) - 1 , true ) ;
auto templDist = genTemplateDistr ( array , array - > GetShortName ( ) , distrRules , distrRulesSt , regionId , templIdx , true , file ) ;
SgStatement * nextSt = firstExec ( st - > lexNext ( ) , st - > fileName ( ) ) ;
if ( ! extractDir )
{
auto cp = nextSt - > controlParent ( ) ;
nextSt - > insertStmtBefore ( * templDist . second , * cp ) ;
nextSt - > insertStmtBefore ( * templDecl . second , * cp ) ;
}
}
}
}
}
}
void insertTempalteDeclarationToMainFile ( SgFile * file , const DataDirective & dataDir ,
const map < string , string > & templateDeclInIncludes ,
const vector < string > & distrRules , const vector < vector < dist > > & distrRulesSt ,
const DIST : : Arrays < int > & allArrays ,
const bool extractDir , const uint64_t regionId ,
const set < string > & includedToThisFile )
{
vector < SgStatement * > modulesAndFuncs ;
getModulesAndFunctions ( file , modulesAndFuncs ) ;
map < string , SgStatement * > modules ;
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
if ( modulesAndFuncs [ i ] - > variant ( ) = = MODULE_STMT )
modules [ modulesAndFuncs [ i ] - > symbol ( ) - > identifier ( ) ] = modulesAndFuncs [ i ] ;
}
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
SgStatement * st = modulesAndFuncs [ i ] ;
if ( st - > variant ( ) = = PROG_HEDR )
{
SgStatement * last = st - > lastNodeOfStmt ( ) ;
set < string > includes ;
for ( SgStatement * stLoc = modulesAndFuncs [ i ] ; stLoc ! = last ; stLoc = stLoc - > lexNext ( ) )
{
if ( stLoc - > variant ( ) = = CONTAINS_STMT )
break ;
if ( stLoc - > fileName ( ) ! = string ( file - > filename ( ) ) )
includes . insert ( stLoc - > fileName ( ) ) ;
}
vector < SgStatement * > useStmt ;
for ( SgStatement * stLoc = modulesAndFuncs [ i ] ; stLoc ! = last ; stLoc = stLoc - > lexNext ( ) )
{
if ( stLoc - > variant ( ) = = USE_STMT )
useStmt . push_back ( stLoc ) ;
}
for ( auto & arrayPair : sortArraysByName ( allArrays . GetArrays ( ) ) )
{
DIST : : Array * array = arrayPair . second ;
if ( array - > IsTemplate ( ) & & ! array - > IsLoopArray ( ) & & array - > GetLocation ( ) . first ! = DIST : : l_MODULE )
{
int templIdx = findTeplatePosition ( array , dataDir ) ;
auto allClones = array - > GetAllClones ( ) ;
vector < SgStatement * > insertList1 , insertList2 ;
auto templDeclP = genTemplateDelc ( array , array - > GetShortName ( ) , file , NULL , true ) ;
string templDecl = templDeclP . first ;
insertList1 . push_back ( templDeclP . second ) ;
for ( auto & elem : allClones )
{
auto tmp = genTemplateDelc ( array , elem . second , file , NULL , true ) ;
templDecl + = tmp . first ;
insertList1 . push_back ( tmp . second ) ;
}
auto tmp = genTemplateDistr ( array , array - > GetShortName ( ) , distrRules , distrRulesSt , regionId , templIdx , true , file ) ;
string templDist = tmp . first ;
insertList2 . push_back ( tmp . second ) ;
for ( auto & elem : allClones )
{
vector < vector < dist > > tmpRuleSt = { elem . first } ;
string strRule = elem . second + " ( " ;
for ( int z = 0 ; z < elem . first . size ( ) ; + + z )
{
if ( z ! = 0 )
strRule + = " , " ;
if ( elem . first [ z ] = = BLOCK )
strRule + = " BLOCK " ;
else if ( elem . first [ z ] = = NONE )
strRule + = " * " ;
else
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
strRule + = " ) " ;
vector < string > tmpStrRule = { strRule } ;
tmp = genTemplateDistr ( array , elem . second , tmpStrRule , tmpRuleSt , regionId , 0 , true , file ) ;
templDist + = tmp . first ;
insertList2 . push_back ( tmp . second ) ;
}
auto tmpDyn = genDynamicDecl ( array , file ) ;
const string templDyn = tmpDyn . first ;
const string fullDecl = createFullTemplateDir ( make_tuple ( templDecl , templDist , templDyn ) ) ;
bool needToInsert = true ;
auto inIncl = templateDeclInIncludes . find ( fullDecl ) ;
if ( inIncl ! = templateDeclInIncludes . end ( ) )
{
auto hasInThisFunc = includes . find ( inIncl - > second ) ;
if ( hasInThisFunc ! = includes . end ( ) )
needToInsert = false ;
}
//check modules
if ( needToInsert )
{
for ( auto & use : useStmt )
{
string name = use - > symbol ( ) - > identifier ( ) ;
auto it = modules . find ( name ) ;
if ( it = = modules . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
else
{
auto last = it - > second - > lastNodeOfStmt ( ) ;
for ( SgStatement * stLoc = it - > second ; stLoc ! = last ; stLoc = stLoc - > lexNext ( ) )
{
const string & templName = array - > GetShortName ( ) ;
if ( stLoc - > variant ( ) = = CONTAINS_STMT )
break ;
const char * comment = stLoc - > comments ( ) ;
if ( comment )
{
if ( string ( comment ) . find ( templName ) ! = string : : npos )
{
needToInsert = false ;
break ;
}
}
}
if ( needToInsert )
break ;
}
}
}
if ( needToInsert )
{
SgStatement * nextSt = firstExec ( st - > lexNext ( ) , st - > fileName ( ) ) ;
if ( ! extractDir )
{
auto cp = nextSt - > controlParent ( ) ;
for ( int z = 0 ; z < insertList1 . size ( ) ; + + z )
{
nextSt - > insertStmtBefore ( * insertList1 [ z ] , * cp ) ;
nextSt - > insertStmtBefore ( * insertList2 [ z ] , * cp ) ;
}
nextSt - > insertStmtBefore ( * tmpDyn . second , * cp ) ;
}
}
}
}
}
}
}
static SgStatement * insertDvmhModule ( SgStatement * firstSt , const vector < SgStatement * > & modulesAndFuncs )
{
for ( auto & st : modulesAndFuncs )
{
if ( st - > variant ( ) = = MODULE_STMT )
{
if ( st - > symbol ( ) - > identifier ( ) = = dvmhModuleName )
return st ;
}
}
SgFuncHedrStmt * moduleN = new SgFuncHedrStmt ( ( char * ) dvmhModuleName . c_str ( ) ) ;
moduleN - > setVariant ( MODULE_STMT ) ;
moduleN - > setlineNumber ( getNextNegativeLineNumber ( ) ) ;
moduleN - > setFileId ( current_file_id ) ;
firstSt - > insertStmtAfter ( * moduleN , * firstSt ) ;
return moduleN ;
}
extern " C " int out_free_form ;
void correctTemplateModuleDeclaration ( const string & folderName )
{
int ifInOneFile = 0 ;
map < SgFile * , vector < SgStatement * > > modsAndFuncs ;
for ( int z = 0 ; z < CurrentProject - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & CurrentProject - > file ( z ) ;
getModulesAndFunctions ( file , modsAndFuncs [ file ] ) ;
for ( auto & elem : modsAndFuncs [ file ] )
if ( elem - > variant ( ) = = MODULE_STMT & & elem - > symbol ( ) - > identifier ( ) = = dvmhModuleName )
if ( elem - > lexNext ( ) - > variant ( ) ! = CONTROL_END )
ifInOneFile + + ;
}
set < string > unitedModuleDecl ;
set < string > fileNames ;
for ( int z = 0 ; z < CurrentProject - > numberOfFiles ( ) ; + + z )
{
SgFile * file = & CurrentProject - > file ( z ) ;
fileNames . insert ( file - > filename ( ) ) ;
for ( auto & elem : modsAndFuncs [ file ] )
{
if ( elem - > variant ( ) = = MODULE_STMT & & elem - > symbol ( ) - > identifier ( ) = = dvmhModuleName )
{
if ( elem - > lexNext ( ) - > variant ( ) ! = CONTROL_END )
{
for ( auto st = elem - > lexNext ( ) ; st ! = elem - > lastNodeOfStmt ( ) ; st = st - > lexNext ( ) )
unitedModuleDecl . insert ( st - > unparse ( ) ) ;
if ( ifInOneFile > 1 )
elem - > deleteStmt ( ) ;
}
else
elem - > deleteStmt ( ) ;
break ;
}
}
}
int t = 0 ;
if ( ifInOneFile > 1 )
{
const string base = " spfTemplateModuleDecl " ;
string fName = ( out_free_form = = 0 ) ? ( base + " .f " ) : ( base + " .f90 " ) ;
while ( fileNames . find ( fName ) ! = fileNames . end ( ) )
{
const string tmpB = base + std : : to_string ( t + + ) ;
fName = ( out_free_form = = 0 ) ? ( tmpB + " .f " ) : ( tmpB + " .f90 " ) ;
}
const string fullPath = ( folderName = = " " ) ? fName : ( folderName + " / " + fName ) ;
FILE * fout = fopen ( fullPath . c_str ( ) , " w " ) ;
if ( fout = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
else
__spf_print ( 1 , " created new file for template module decl -> %s \n " , fullPath . c_str ( ) ) ;
const string shift = ( out_free_form = = 0 ) ? " " : " " ;
const string first = shift + " module " + dvmhModuleName + " \n " ;
const string last = shift + " end module " + " \n " ;
string out = first ;
for ( auto & elem : unitedModuleDecl )
out + = elem ;
out + = last ;
fwrite ( out . c_str ( ) , sizeof ( char ) , out . size ( ) , fout ) ;
fclose ( fout ) ;
}
}
static void findAllArrayRefs ( SgExpression * ex , set < SgSymbol * > & refs )
{
if ( ex )
{
if ( isArrayRef ( ex ) )
{
SgSymbol * symb = ex - > symbol ( ) ;
if ( symb - > type ( ) )
{
if ( symb - > type ( ) - > variant ( ) = = T_ARRAY )
refs . insert ( ex - > symbol ( ) ) ;
}
}
findAllArrayRefs ( ex - > lhs ( ) , refs ) ;
findAllArrayRefs ( ex - > rhs ( ) , refs ) ;
}
}
static bool hasPrivateAllInModule ( SgStatement * mod )
{
bool ret = false ;
if ( mod & & mod - > variant ( ) = = MODULE_STMT )
{
for ( SgStatement * st = mod - > lexNext ( ) ; st ! = mod - > lastNodeOfStmt ( ) ; st = st - > lexNext ( ) )
{
if ( isSgExecutableStatement ( st ) )
break ;
if ( st - > variant ( ) = = PRIVATE_STMT )
{
SgVarListDeclStmt * listPrivates = isSgVarListDeclStmt ( st ) ;
checkNull ( listPrivates , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( listPrivates - > numberOfVars ( ) = = 0 )
{
ret = true ;
break ;
}
}
}
}
return ret ;
}
void insertTemplateModuleUse ( SgFile * file , const set < uint64_t > & regNums , const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls )
{
int funcNum = file - > numberOfFunctions ( ) ;
map < string , set < string > > moduleUseMap = createMapOfModuleUses ( file ) ;
vector < SgStatement * > modules ;
findModulesInFile ( file , modules ) ;
for ( int i = 0 ; i < funcNum ; + + i )
{
SgStatement * st = file - > functions ( i ) ;
auto cp = st - > controlParent ( ) ;
if ( cp - > variant ( ) ! = GLOBAL & &
cp - > variant ( ) ! = PROG_HEDR & &
cp - > variant ( ) ! = PROC_HEDR & &
cp - > variant ( ) ! = FUNC_HEDR )
continue ;
else
{
//check for module
if ( cp - > variant ( ) = = PROC_HEDR | | cp - > variant ( ) = = FUNC_HEDR )
{
if ( cp - > controlParent ( ) - > variant ( ) = = MODULE_STMT )
continue ;
}
}
set < SgSymbol * > refs ;
set < string > modUse ;
for ( st = st - > lexNext ( ) ; st ; st = st - > lexNext ( ) )
{
if ( isSgExecutableStatement ( st ) )
break ;
if ( st - > variant ( ) = = VAR_DECL | | st - > variant ( ) = = VAR_DECL_90 )
{
for ( int z = 0 ; z < 3 ; + + z )
findAllArrayRefs ( st - > expr ( z ) , refs ) ;
}
else if ( st - > variant ( ) = = USE_STMT )
modUse . insert ( st - > symbol ( ) - > identifier ( ) ) ;
}
set < DIST : : Array * > templates ;
for ( auto & arrayR : refs )
{
SgStatement * decl = declaratedInStmt ( arrayR ) ;
DIST : : Array * currArray = getArrayFromDeclarated ( decl , arrayR - > identifier ( ) ) ;
checkNull ( currArray , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( ! currArray - > IsNotDistribute ( ) )
{
set < DIST : : Array * > realRefs ;
getRealArrayRefs ( currArray , currArray , realRefs , arrayLinksByFuncCalls ) ;
if ( ! ( realRefs . size ( ) = = 1 & & realRefs . find ( currArray ) ! = realRefs . end ( ) ) )
continue ;
for ( auto & num : regNums )
{
auto templ = currArray - > GetTemplateArray ( num ) ;
if ( templ )
{
if ( templ - > GetLocation ( ) . first = = DIST : : l_MODULE )
{
bool needToAdd = true ;
if ( modUse . find ( dvmhModuleName ) = = modUse . end ( ) )
{
for ( auto & elem : modUse )
{
auto it = moduleUseMap . find ( elem ) ;
if ( it ! = moduleUseMap . end ( ) )
{
SgStatement * currMod = NULL ;
for ( auto & modV : modules )
if ( modV - > symbol ( ) - > identifier ( ) = = elem )
currMod = modV ;
if ( it - > second . find ( dvmhModuleName ) ! = it - > second . end ( ) & & ! hasPrivateAllInModule ( currMod ) )
{
needToAdd = false ;
break ;
}
}
}
}
if ( needToAdd )
templates . insert ( templ ) ;
}
}
}
}
}
if ( templates . size ( ) )
{
st = file - > functions ( i ) ;
SgStatement * useSt = new SgStatement ( USE_STMT ) ;
useSt - > setSymbol ( * findSymbolOrCreate ( file , dvmhModuleName ) ) ;
useSt - > setlineNumber ( getNextNegativeLineNumber ( ) ) ;
st - > insertStmtAfter ( * useSt , * st ) ;
}
}
}
static set < SgStatement * > filterAllocateStats ( SgFile * file , const vector < SgStatement * > & currentAlloc , const string & array )
{
set < SgStatement * > filtered ;
const string fileName = file - > filename ( ) ;
for ( auto & stat : currentAlloc )
{
set < string > arraySyns ;
arraySyns . insert ( array ) ;
if ( stat - > fileName ( ) ! = fileName )
if ( ! stat - > switchToFile ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
2025-02-18 13:45:20 +03:00
SgExpression * list = stat - > expr ( 0 ) ;
bool find = false ;
while ( list )
{
if ( list - > lhs ( ) & & list - > lhs ( ) - > symbol ( ) )
{
if ( OriginalSymbol ( list - > lhs ( ) - > symbol ( ) ) - > identifier ( ) = = array )
{
find = true ;
break ;
}
}
list = list - > rhs ( ) ;
}
2023-09-14 19:43:13 +03:00
2025-02-18 13:45:20 +03:00
if ( find )
filtered . insert ( stat ) ;
2023-09-14 19:43:13 +03:00
SgFile : : switchToFile ( fileName ) ;
}
//TODO: removed this checking 17.04.2020
/*if (filtered.size() != 1)
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ; */
return filtered ;
}
// by file and function
static map < string , map < string , set < string > > > dynamicDirsByFile ;
static map < string , map < string , set < string > > > dynamicArraysByFile ;
static map < string , map < string , set < string > > > alignArraysByFile ;
static map < string , map < string , map < string , pair < SgExpression * , SgExpression * > > > > insertedShadowByFile ;
static inline void addStringToComments ( const vector < string > & toInsert , map < string , map < int , set < string > > > & commentsToInclude ,
const string & fileName , const int line )
{
//check for file in project
int totalFiles = CurrentProject - > numberOfFiles ( ) ;
string wasFile = current_file - > filename ( ) ;
bool exist = false ;
for ( int z = 0 ; z < totalFiles & & ! exist ; + + z )
if ( CurrentProject - > file ( z ) . filename ( ) = = fileName )
exist = true ;
SgFile : : switchToFile ( wasFile ) ;
if ( exist )
return ;
auto currF = commentsToInclude . find ( fileName ) ;
if ( currF = = commentsToInclude . end ( ) )
currF = commentsToInclude . insert ( currF , make_pair ( fileName , map < int , set < string > > ( ) ) ) ;
auto place = currF - > second . find ( line ) ;
if ( place = = currF - > second . end ( ) )
place = currF - > second . insert ( place , make_pair ( line , set < string > ( ) ) ) ;
for ( auto & str : toInsert )
{
if ( str = = " " )
continue ;
bool needToInsert = true ;
for ( auto & elem : currF - > second )
{
for ( auto addedStr : elem . second )
{
if ( addedStr = = str )
{
needToInsert = false ;
break ;
}
}
if ( needToInsert = = false )
break ;
}
if ( needToInsert )
place - > second . insert ( str ) ;
}
}
static void addComment ( SgStatement * st , const string & toAdd , bool needUniq = false )
{
if ( needUniq )
{
char * comm = st - > comments ( ) ;
if ( comm = = NULL )
st - > addComment ( toAdd . c_str ( ) ) ;
else if ( string ( comm ) . find ( toAdd ) = = string : : npos )
st - > addComment ( toAdd . c_str ( ) ) ;
}
else
st - > addComment ( toAdd . c_str ( ) ) ;
}
static string getFullArrayName ( SgSymbol * symb )
{
string fullArrayName = " " ;
if ( symb - > type ( ) - > variant ( ) = = T_ARRAY )
{
auto uniqKey = getFromUniqTable ( symb ) ;
fullArrayName = getShortName ( uniqKey ) ;
}
return fullArrayName ;
}
static vector < SgExpression * > createVarListFromDecl ( const int currV , SgStatement * st )
{
vector < SgExpression * > varList ;
if ( currV = = COMM_STAT )
{
map < string , vector < SgExpression * > > commonBlocks ;
getCommonBlocksRef ( commonBlocks , st , st - > lexNext ( ) ) ;
for ( auto & elem : commonBlocks )
{
for ( auto & commList : elem . second )
{
SgExpression * list = commList - > lhs ( ) ;
while ( list )
{
varList . push_back ( list - > lhs ( ) ) ;
list = list - > rhs ( ) ;
}
}
}
}
else
{
SgVarDeclStmt * varDecl = ( SgVarDeclStmt * ) st ;
SgExpression * varL = varDecl - > varList ( ) ;
while ( varL )
{
varList . push_back ( varL - > lhs ( ) ) ;
varL = varL - > rhs ( ) ;
}
}
return varList ;
}
static string getFullArrayNameOfParameter ( SgStatement * fPointer , const int numOfParams , const int currPar )
{
string oldFile = current_file - > filename ( ) ; //save file
if ( ! fPointer - > switchToFile ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto hedrOfIface = ( SgProgHedrStmt * ) fPointer ;
if ( hedrOfIface - > numberOfParameters ( ) ! = numOfParams )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
auto sInIface = hedrOfIface - > parameter ( currPar ) ;
const string fullArrayName = getFullArrayName ( sInIface ) ;
if ( SgFile : : switchToFile ( oldFile ) = = - 1 )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
return fullArrayName ;
}
static void createInherit ( pair < SgStatement * , SgStatement * > & inheritDir , SgStatement * insertBefore , SgExpression * ref )
{
if ( inheritDir . first = = NULL )
{
inheritDir . first = new SgStatement ( DVM_INHERIT_DIR ) ;
SgExpression * list = new SgExpression ( EXPR_LIST ) ;
list - > setLhs ( ref ) ;
inheritDir . first - > setExpression ( 0 , * list ) ;
inheritDir . second = insertBefore ;
}
else
{
SgExpression * list = new SgExpression ( EXPR_LIST ) ;
list - > setLhs ( ref ) ;
list - > setRhs ( inheritDir . first - > expr ( 0 ) ) ;
inheritDir . first - > setExpression ( 0 , * list ) ;
}
}
void insertDistributionToFile ( SgFile * file , const char * fin_name , const DataDirective & dataDir ,
const set < string > & distrArrays , const vector < string > & distrRules ,
const vector < vector < dist > > & distrRulesSt ,
const vector < string > & alignRules , const map < string , vector < LoopGraph * > > & loopGraph ,
const DIST : : Arrays < int > & allArrays ,
DIST : : GraphCSR < int , double , attrType > & reducedG ,
map < string , map < int , set < string > > > & commentsToInclude ,
map < string , string > & templateDeclInIncludes ,
const bool extractDir , vector < Messages > & messagesForFile ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
const map < string , FuncInfo * > & funcsInFile ,
const uint64_t regionId , const set < string > & allFileNames )
{
const string currFilename = file - > filename ( ) ;
vector < SgStatement * > modulesAndFuncs ;
getModulesAndFunctions ( file , modulesAndFuncs ) ;
SgStatement * dvmhModule = NULL ;
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
SgStatement * isModule = ( modulesAndFuncs [ i ] - > variant ( ) = = MODULE_STMT ) ? modulesAndFuncs [ i ] : NULL ;
if ( isModule )
{
dvmhModule = insertDvmhModule ( file - > firstStatement ( ) , modulesAndFuncs ) ;
break ;
}
}
map < SgStatement * , set < string > > dvmhModuleSt ;
if ( dvmhModule )
dvmhModuleSt [ dvmhModule ] = set < string > ( ) ;
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
SgStatement * st = modulesAndFuncs [ i ] ;
FuncInfo * currFI = NULL ;
if ( st - > variant ( ) ! = MODULE_STMT )
{
for ( auto & funcs : funcsInFile )
if ( funcs . second - > funcPointer - > GetOriginal ( ) = = st )
currFI = funcs . second ;
if ( currFI = = NULL )
{
__spf_print ( 1 , " function '%s' not found in map of functons \n " , st - > symbol ( ) - > identifier ( ) ) ;
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
}
}
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
const auto lineRange = make_pair ( st - > lineNumber ( ) , lastNode - > lineNumber ( ) ) ;
const string filename = st - > fileName ( ) ;
set < string > templateDelc ;
SgStatement * isModule = ( st - > variant ( ) = = MODULE_STMT ) ? st : NULL ;
bool isMain = ( st - > variant ( ) = = PROG_HEDR ) ;
const string modName = st - > symbol ( ) - > identifier ( ) ;
map < string , pair < SgExpression * , SgExpression * > > & insertedShadow = insertedShadowByFile [ fin_name ] [ modName ] ;
set < string > & dynamicDirs = dynamicDirsByFile [ fin_name ] [ modName ] ;
set < string > & dynamicArraysAdded = dynamicArraysByFile [ fin_name ] [ modName ] ;
set < string > & alignArrays = alignArraysByFile [ fin_name ] [ modName ] ;
// PAIR<dir, insertBefore>
pair < SgStatement * , SgStatement * > inheritDir = make_pair ( ( SgStatement * ) NULL , ( SgStatement * ) NULL ) ;
map < SgStatement * , pair < SgStatement * , SgStatement * > > inheritDirIface ;
while ( st ! = lastNode )
{
if ( st = = NULL )
{
messagesForFile . push_back ( Messages ( ERROR , 1 , R128 , L " internal error in analysis, parallel directives will not be generated for this file! " , 3008 ) ) ;
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
const int currV = st - > variant ( ) ;
if ( currV = = VAR_DECL | | currV = = VAR_DECL_90 | | currV = = DIM_STAT | | currV = = COMM_STAT )
{
auto varList = createVarListFromDecl ( currV , st ) ;
set < DIST : : Array * > dynamicArrays ;
set < DIST : : Array * > dynamicArraysLocal ;
for ( auto & varExp : varList )
{
if ( isArrayRef ( varExp ) )
{
SgSymbol * currSymb = OriginalSymbol ( varExp - > symbol ( ) ) ;
const string fullArrayName = getFullArrayName ( currSymb ) ;
const string arrayName = string ( currSymb - > identifier ( ) ) ;
if ( isModule = = NULL & & extractDir = = false )
{
SgStatement * st_cp = st - > controlParent ( ) ;
if ( st_cp - > variant ( ) = = PROC_HEDR | | st_cp - > variant ( ) = = FUNC_HEDR )
{
if ( st_cp - > controlParent ( ) - > variant ( ) = = INTERFACE_STMT ) // interface in procedure, check distribution state
{
auto hedr = ( ( SgProgHedrStmt * ) st_cp ) ;
int numOfParams = hedr - > numberOfParameters ( ) ;
int z = 0 ;
for ( ; z < numOfParams ; + + z )
{
auto t = hedr - > parameter ( z ) ;
if ( t - > identifier ( ) = = arrayName )
break ;
}
if ( numOfParams )
{
if ( z = = numOfParams )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
const string fName = hedr - > name ( ) . identifier ( ) ;
auto itIface = currFI - > interfaceBlocks . find ( fName ) ;
if ( itIface = = currFI - > interfaceBlocks . end ( ) )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
if ( itIface - > second = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
set < string > fullArrayNames ;
if ( itIface - > second - > fullCopiesOfThisFunction . size ( ) = = 0 )
if ( itIface - > second - > funcPointer - > variant ( ) > 0 )
fullArrayNames . insert ( getFullArrayNameOfParameter ( itIface - > second - > funcPointer - > GetOriginal ( ) , numOfParams , z ) ) ;
for ( auto & fullCopies : itIface - > second - > fullCopiesOfThisFunction )
if ( fullCopies - > funcPointer - > variant ( ) > 0 )
fullArrayNames . insert ( getFullArrayNameOfParameter ( fullCopies - > funcPointer - > GetOriginal ( ) , numOfParams , z ) ) ;
bool needToInherit = false ;
for ( auto & fullArrayName : fullArrayNames )
if ( distrArrays . find ( fullArrayName ) ! = distrArrays . end ( ) )
needToInherit = true ;
if ( needToInherit )
{
auto it = inheritDirIface . find ( st_cp ) ;
if ( it = = inheritDirIface . end ( ) )
it = inheritDirIface . insert ( it , make_pair ( st_cp , make_pair ( ( SgStatement * ) NULL , ( SgStatement * ) NULL ) ) ) ;
createInherit ( it - > second , st_cp , new SgVarRefExp ( currSymb ) ) ;
}
}
}
}
}
if ( distrArrays . find ( fullArrayName ) ! = distrArrays . end ( ) )
{
const vector < SgStatement * > & allocatableStmtsCopy = getAttributes < SgStatement * , SgStatement * > ( st , set < int > { ALLOCATE_STMT } ) ;
set < SgStatement * > allocatableStmts ;
if ( allocatableStmtsCopy . size ( ) )
allocatableStmts = filterAllocateStats ( file , allocatableStmtsCopy , currSymb - > identifier ( ) ) ;
2025-02-10 17:16:15 +03:00
pair < DIST : : Array * , string > dirWithArray = getNewDirective ( fullArrayName , distrRules , alignRules , dataDir , allocatableStmts ) ;
2023-09-14 19:43:13 +03:00
string toInsert = dirWithArray . second ;
if ( toInsert ! = " " )
{
auto alignIt = alignArrays . find ( fullArrayName ) ;
if ( alignIt = = alignArrays . end ( ) & & ! extractDir )
alignArrays . insert ( alignIt , fullArrayName ) ;
else if ( alignIt ! = alignArrays . end ( ) & & extractDir )
alignArrays . erase ( alignIt ) ;
else
toInsert = " " ;
const pair < templateDir , string > & templDir =
getNewTemplateDirective ( dirWithArray . first , allArrays , reducedG , dataDir , distrRules , distrRulesSt , arrayLinksByFuncCalls , regionId , isModule , isMain , file , messagesForFile ) ;
string templDecl = templDir . first . templDecl . first ; //std::get<0>(templDir.first);
//if array is inherit array
if ( templDir . second = = " !DVM$ INHERIT \n " )
{
toInsert = " " ;
if ( extractDir = = false )
createInherit ( inheritDir , st , new SgVarRefExp ( findSymbolOrCreate ( file , dirWithArray . first - > GetShortName ( ) ) ) ) ;
}
else
dynamicArraysLocal . insert ( dirWithArray . first ) ;
dynamicArrays . insert ( dirWithArray . first ) ;
if ( templDir . second = = " !DVM$ INHERIT \n " & & templDir . first . isTemplateInModule )
templDecl = " " ;
else
{
if ( templateDelc . find ( templDecl ) = = templateDelc . end ( ) )
templateDelc . insert ( templDecl ) ;
else
templDecl = " " ;
if ( templDecl ! = " " )
templDecl = createFullTemplateDir ( make_tuple ( templDir . first . templDecl . first , templDir . first . templDist . first , templDir . first . templDyn . first ) ) ;
}
const bool isFromInclude = allFileNames . find ( st - > fileName ( ) ) = = allFileNames . end ( ) ;
if ( isMain )
templDecl = " " ;
else
{
set < DIST : : Array * > realRefs ;
getRealArrayRefs ( dirWithArray . first , dirWithArray . first , realRefs , arrayLinksByFuncCalls ) ;
for ( auto & elem : realRefs )
{
if ( elem - > GetTemplateArray ( regionId ) - > GetLocation ( ) . first = = DIST : : l_MODULE )
{
templDecl = " " ;
break ;
}
}
}
vector < string > toAdd ;
if ( isModule & & dvmhModule )
toAdd = { toInsert , " " } ;
else
toAdd = { templDecl , toInsert } ;
if ( extractDir )
{
if ( allocatableStmts . size ( ) )
{
if ( isModule & & dvmhModule )
{
for ( auto & elem : allocatableStmts )
{
if ( elem - > fileName ( ) ! = currFilename )
continue ;
extractComments ( elem - > lexNext ( ) , toAdd [ 0 ] + toAdd [ 1 ] ) ;
}
extractComments ( st , ( " !DVM$ ALIGN :: " + dirWithArray . first - > GetShortName ( ) + " \n " ) . c_str ( ) ) ;
}
else
{
for ( auto & elem : allocatableStmts )
{
if ( elem - > fileName ( ) ! = currFilename )
continue ;
extractComments ( elem - > lexNext ( ) , toInsert ) ;
}
extractComments ( st , ( templDecl + " !DVM$ ALIGN :: " + dirWithArray . first - > GetShortName ( ) + " \n " ) . c_str ( ) ) ;
}
}
else
extractComments ( st , toAdd [ 0 ] + toAdd [ 1 ] ) ;
}
else
{
if ( allocatableStmts . size ( ) )
{
if ( isModule & & dvmhModule )
{
for ( auto & elem : allocatableStmts )
{
if ( elem - > fileName ( ) ! = currFilename )
continue ;
if ( elem - > lexNext ( ) - > variant ( ) ! = CONT_STAT )
elem - > insertStmtAfter ( * new SgContinueStmt ( ) , * elem - > controlParent ( ) ) ;
addComment ( elem - > lexNext ( ) , ( toAdd [ 0 ] + toAdd [ 1 ] ) . c_str ( ) , true ) ;
}
const string newDecl = " !DVM$ ALIGN :: " + dirWithArray . first - > GetShortName ( ) + " \n " ;
if ( isFromInclude )
addStringToComments ( { newDecl } , commentsToInclude , st - > fileName ( ) , st - > lineNumber ( ) ) ;
else
st - > addComment ( newDecl . c_str ( ) ) ;
}
else
{
for ( auto & elem : allocatableStmts )
{
if ( elem - > fileName ( ) ! = currFilename )
continue ;
if ( elem - > lexNext ( ) - > variant ( ) ! = CONT_STAT )
elem - > insertStmtAfter ( * new SgContinueStmt ( ) , * elem - > controlParent ( ) ) ;
addComment ( elem - > lexNext ( ) , toInsert . c_str ( ) , true ) ;
}
const string newDecl = templDecl + " !DVM$ ALIGN :: " + dirWithArray . first - > GetShortName ( ) + " \n " ;
if ( isFromInclude )
addStringToComments ( { newDecl } , commentsToInclude , st - > fileName ( ) , st - > lineNumber ( ) ) ;
else
st - > addComment ( newDecl . c_str ( ) ) ;
}
}
else
{
if ( isFromInclude )
addStringToComments ( { toAdd } , commentsToInclude , st - > fileName ( ) , st - > lineNumber ( ) ) ;
else
st - > addComment ( ( toAdd [ 0 ] + toAdd [ 1 ] ) . c_str ( ) ) ;
}
if ( isFromInclude )
if ( templDecl ! = " " )
templateDeclInIncludes [ templDecl ] = st - > fileName ( ) ;
if ( isModule & & dvmhModule )
{
if ( dvmhModuleSt [ dvmhModule ] . find ( templDir . first . templDyn . first ) = = dvmhModuleSt [ dvmhModule ] . end ( ) )
{
dvmhModule - > insertStmtAfter ( * templDir . first . templDyn . second , * dvmhModule ) ;
dvmhModuleSt [ dvmhModule ] . insert ( templDir . first . templDyn . first ) ;
}
if ( dvmhModuleSt [ dvmhModule ] . find ( templDir . first . templDecl . first ) = = dvmhModuleSt [ dvmhModule ] . end ( ) )
{
for ( int z = 0 ; z < templDir . first . templDecl . second . size ( ) ; + + z )
dvmhModule - > insertStmtAfter ( * templDir . first . templDecl . second [ z ] , * dvmhModule ) ;
dvmhModuleSt [ dvmhModule ] . insert ( templDir . first . templDecl . first ) ;
}
if ( dvmhModuleSt [ dvmhModule ] . find ( templDir . first . templDist . first ) = = dvmhModuleSt [ dvmhModule ] . end ( ) )
{
for ( int z = 0 ; z < templDir . first . templDist . second . size ( ) ; + + z )
dvmhModule - > insertStmtAfter ( * templDir . first . templDist . second [ z ] , * dvmhModule ) ;
dvmhModuleSt [ dvmhModule ] . insert ( templDir . first . templDist . first ) ;
}
const string useS = dvmhModule - > symbol ( ) - > identifier ( ) ;
string str = string ( " use " ) + useS ;
if ( dvmhModuleSt [ isModule ] . find ( str ) = = dvmhModuleSt [ isModule ] . end ( ) )
{
dvmhModuleSt [ isModule ] . insert ( str ) ;
SgStatement * useSt = new SgStatement ( USE_STMT ) ;
useSt - > setSymbol ( * findSymbolOrCreate ( file , useS ) ) ;
useSt - > setlineNumber ( getNextNegativeLineNumber ( ) ) ;
isModule - > insertStmtAfter ( * useSt , * isModule ) ;
}
}
}
}
else // may be INHERIT array?
{
SgStatement * st_cp = st - > controlParent ( ) ;
if ( ! extractDir & & ( st_cp - > variant ( ) = = PROC_HEDR | | st_cp - > variant ( ) = = FUNC_HEDR ) )
{
SgProgHedrStmt * hedr = ( SgProgHedrStmt * ) st_cp ;
for ( int z = 0 ; z < hedr - > numberOfParameters ( ) ; + + z )
{
if ( hedr - > parameter ( z ) - > identifier ( ) = = string ( currSymb - > identifier ( ) ) )
{
auto array = getArrayFromDeclarated ( declaratedInStmt ( currSymb ) , currSymb - > identifier ( ) ) ;
checkNull ( array , convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
set < DIST : : Array * > realRefs ;
getRealArrayRefs ( array , array , realRefs , arrayLinksByFuncCalls ) ;
bool distributed = false ;
int rank = - 1 ;
bool diffRank = false ;
for ( auto & elem : realRefs )
{
if ( elem - > IsNotDistribute ( ) = = false )
{
distributed = true ;
int oldRank = rank ;
rank = elem - > GetDimSize ( ) ;
if ( oldRank ! = - 1 & & oldRank ! = elem - > GetDimSize ( ) )
diffRank = true ;
}
}
if ( distributed & & ! diffRank & & rank = = array - > GetDimSize ( ) )
createInherit ( inheritDir , st , new SgVarRefExp ( currSymb ) ) ;
break ;
}
}
}
}
}
}
}
string toInsert = " !DVM$ DYNAMIC " ;
set < string > toInsertArrays ;
for ( auto & array : dynamicArraysLocal )
{
if ( extractDir )
{
if ( dynamicArraysAdded . find ( array - > GetShortName ( ) ) ! = dynamicArraysAdded . end ( ) )
{
dynamicArraysAdded . erase ( array - > GetShortName ( ) ) ;
toInsertArrays . insert ( array - > GetShortName ( ) ) ;
}
}
else
{
if ( dynamicArraysAdded . find ( array - > GetShortName ( ) ) = = dynamicArraysAdded . end ( ) )
{
dynamicArraysAdded . insert ( array - > GetShortName ( ) ) ;
toInsertArrays . insert ( array - > GetShortName ( ) ) ;
}
}
}
int z = 0 ;
for ( auto & array : toInsertArrays )
{
if ( z ! = 0 )
toInsert + = " , " ;
toInsert + = array ;
+ + z ;
}
if ( z ! = 0 )
{
toInsert + = " \n " ;
auto dynIt = dynamicDirs . find ( toInsert ) ;
if ( dynIt = = dynamicDirs . end ( ) & & ! extractDir )
dynamicDirs . insert ( dynIt , toInsert ) ;
else if ( extractDir & & dynIt ! = dynamicDirs . end ( ) )
dynamicDirs . erase ( dynIt ) ;
else
toInsert = " " ;
}
else
toInsert = " " ;
if ( dynamicArrays . size ( ) > 0 )
createShadowSpec ( loopGraph , arrayLinksByFuncCalls , dynamicArrays ) ;
if ( toInsert ! = " " )
{
if ( ! strcmp ( st - > fileName ( ) , fin_name ) )
{
if ( extractDir )
extractComments ( st , toInsert ) ;
else
st - > addComment ( toInsert . c_str ( ) ) ;
}
else
{
if ( ! extractDir )
addStringToComments ( { toInsert } , commentsToInclude , st - > fileName ( ) , st - > lineNumber ( ) ) ;
}
}
}
st = st - > lexNext ( ) ;
}
if ( extractDir = = false )
{
if ( inheritDir . second )
{
inheritDir . second - > insertStmtBefore ( * inheritDir . first , * inheritDir . second - > controlParent ( ) ) ;
SgStatement * dynamicDir = new SgStatement ( DVM_DYNAMIC_DIR ) ;
dynamicDir - > setExpression ( 0 , inheritDir . first - > expr ( 0 ) - > copy ( ) ) ;
inheritDir . second - > insertStmtBefore ( * dynamicDir , * inheritDir . second - > controlParent ( ) ) ;
}
for ( auto & inherit : inheritDirIface )
{
SgStatement * dynamicDir = new SgStatement ( DVM_DYNAMIC_DIR ) ;
dynamicDir - > setExpression ( 0 , inherit . second . first - > expr ( 0 ) - > copy ( ) ) ;
inherit . first - > insertStmtAfter ( * dynamicDir , * inherit . first ) ;
inherit . first - > insertStmtAfter ( * inherit . second . first , * inherit . first ) ;
}
}
}
if ( extractDir )
{
if ( dvmhModule )
dvmhModule - > deleteStmt ( ) ;
}
else
{
//TODO: do it better!!
if ( dvmhModule )
{
if ( dvmhModule - > lexNext ( ) - > variant ( ) = = CONTROL_END )
dvmhModule - > deleteStmt ( ) ;
}
}
}
void insertShadowSpecToFile ( SgFile * file , const char * fin_name , const set < string > & distrArrays ,
DIST : : GraphCSR < int , double , attrType > & reducedG ,
map < string , map < int , set < string > > > & commentsToInclude ,
const bool extractDir , vector < Messages > & messagesForFile ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays )
{
vector < SgStatement * > modulesAndFuncs ;
getModulesAndFunctions ( file , modulesAndFuncs ) ;
for ( int i = 0 ; i < modulesAndFuncs . size ( ) ; + + i )
{
SgStatement * st = modulesAndFuncs [ i ] ;
SgStatement * lastNode = st - > lastNodeOfStmt ( ) ;
const string modName = st - > symbol ( ) - > identifier ( ) ;
map < string , pair < SgExpression * , SgExpression * > > & insertedShadow = insertedShadowByFile [ fin_name ] [ modName ] ;
while ( st ! = lastNode )
{
if ( st = = NULL )
{
messagesForFile . push_back ( Messages ( ERROR , 1 , R128 , L " internal error in analysis, parallel directives will not be generated for this file! " , 3008 ) ) ;
__spf_print ( 1 , " internal error in analysis, parallel directives will not be generated for this file! \n " ) ;
break ;
}
if ( st - > variant ( ) = = CONTAINS_STMT )
break ;
const int currV = st - > variant ( ) ;
if ( currV = = VAR_DECL | | currV = = VAR_DECL_90 | | currV = = DIM_STAT | | currV = = COMM_STAT )
{
auto varList = createVarListFromDecl ( currV , st ) ;
set < DIST : : Array * > declaratedDistrArrays ;
for ( auto & varExpr : varList )
{
if ( isArrayRef ( varExpr ) )
{
SgSymbol * currSymb = OriginalSymbol ( varExpr - > symbol ( ) ) ;
const string fullArrayName = getFullArrayName ( currSymb ) ;
if ( distrArrays . find ( fullArrayName ) ! = distrArrays . end ( ) )
{
auto uniqKey = getFromUniqTable ( currSymb ) ;
auto itArr = declaredArrays . find ( uniqKey ) ;
if ( itArr ! = declaredArrays . end ( ) )
declaratedDistrArrays . insert ( itArr - > second . first ) ;
}
}
}
vector < pair < SgExpression * , SgExpression * > > shadowsSpecs ;
vector < string > shadowsSpecsString ;
for ( auto & arrayPair : sortArraysByName ( declaratedDistrArrays ) )
{
DIST : : Array * array = arrayPair . second ;
const vector < pair < int , int > > currSpec = array - > GetShadowSpec ( ) ;
bool needToGen = false ;
for ( auto & elem : currSpec )
if ( elem . first ! = 0 | | elem . second ! = 0 )
needToGen = true ;
if ( needToGen )
{
string shadowSpecInsert = " !DVM$ SHADOW " + array - > GetShortName ( ) + " ( " ;
for ( int k = 0 ; k < currSpec . size ( ) ; + + k )
{
char buf [ 256 ] ;
sprintf ( buf , " %d:%d " , currSpec [ k ] . first , currSpec [ k ] . second ) ;
shadowSpecInsert + = buf ;
if ( k ! = currSpec . size ( ) - 1 )
shadowSpecInsert + = " , " ;
}
shadowSpecInsert + = " ) \n " ;
shadowsSpecsString . push_back ( shadowSpecInsert ) ;
pair < SgExpression * , SgExpression * > newSpec = genShadowSpec ( file , make_pair ( array - > GetShortName ( ) , currSpec ) ) ;
if ( newSpec . first = = NULL | | newSpec . second = = NULL )
printInternalError ( convertFileName ( __FILE__ ) . c_str ( ) , __LINE__ ) ;
shadowsSpecs . push_back ( newSpec ) ;
}
}
if ( shadowsSpecsString . size ( ) > 0 )
{
if ( ! strcmp ( st - > fileName ( ) , fin_name ) )
{
if ( ! extractDir )
{
for ( int i = 0 ; i < shadowsSpecs . size ( ) ; + + i )
{
SgStatement * tmp = new SgStatement ( DVM_SHADOW_DIR , NULL , NULL , shadowsSpecs [ i ] . first , shadowsSpecs [ i ] . second , NULL ) ;
st - > insertStmtAfter ( * tmp , * st - > controlParent ( ) ) ;
insertedShadow . insert ( make_pair ( shadowsSpecs [ i ] . first - > unparse ( ) , shadowsSpecs [ i ] ) ) ;
}
}
else
{
for ( int i = 0 ; i < shadowsSpecs . size ( ) ; + + i )
{
auto it = insertedShadow . find ( shadowsSpecs [ i ] . first - > unparse ( ) ) ;
if ( it ! = insertedShadow . end ( ) )
insertedShadow . erase ( it ) ;
}
}
}
else
{
if ( ! extractDir )
addStringToComments ( shadowsSpecsString , commentsToInclude , st - > fileName ( ) , st - > lineNumber ( ) ) ;
}
}
}
st = st - > lexNext ( ) ;
}
}
}
void insertDistributionToFile ( const char * origFile , const char * outFile , const map < int , set < string > > & commentsToInclude )
{
FILE * F = fopen ( origFile , " r " ) ;
vector < string > lines ;
set < string > uniqLines ;
while ( ! feof ( F ) )
{
char buf [ 8192 ] ;
char * res = fgets ( buf , 8192 , F ) ;
if ( res )
{
string bufStr ( buf ) ;
convertToLower ( bufStr ) ;
bool iSPF = isSPF_comment ( bufStr ) ;
bool iDVM = isDVM_comment ( bufStr ) ;
if ( ( iSPF & & ( keepSpfDirs = = 0 ) ) | | iDVM )
{
lines . push_back ( " " ) ;
uniqLines . insert ( " " ) ;
}
else
{
lines . push_back ( buf ) ;
uniqLines . insert ( buf ) ;
}
}
}
fclose ( F ) ;
F = fopen ( outFile , " w " ) ;
//save order
int idx = 0 ;
for ( auto k = commentsToInclude . begin ( ) ; k ! = commentsToInclude . end ( ) ; + + k )
{
int currLine = k - > first - 1 ;
if ( currLine > idx )
{
if ( idx < lines . size ( ) )
{
for ( ; idx < currLine ; + + idx )
if ( lines [ idx ] ! = " " & & lines [ idx ] ! = " \n " )
fprintf ( F , " %s " , lines [ idx ] . c_str ( ) ) ;
}
for ( auto it = k - > second . begin ( ) ; it ! = k - > second . end ( ) ; + + it )
fprintf ( F , " %s " , ( * it ) . c_str ( ) ) ;
}
else
for ( auto it = k - > second . begin ( ) ; it ! = k - > second . end ( ) ; + + it )
fprintf ( F , " %s " , ( * it ) . c_str ( ) ) ;
}
for ( ; idx < lines . size ( ) ; + + idx )
if ( lines [ idx ] ! = " " & & lines [ idx ] ! = " \n " )
fprintf ( F , " %s " , lines [ idx ] . c_str ( ) ) ;
fclose ( F ) ;
}
void insertDistributeDirsToParallelRegions ( const vector < ParallelRegionLines > * currLines ,
const vector < Statement * > & reDistrRulesBefore ,
const vector < Statement * > & reDistrRulesAfter ,
const vector < Statement * > & reAlignRules )
{
if ( currLines )
{
for ( int i = 0 ; i < currLines - > size ( ) ; + + i )
{
SgStatement * insertBefore = ( * currLines ) [ i ] . stats . first ;
SgStatement * insertAfter = ( * currLines ) [ i ] . stats . second ;
if ( insertBefore = = NULL | | insertAfter = = NULL )
continue ;
SgStatement * controlParentAfter = insertAfter - > controlParent ( ) ;
if ( insertAfter - > variant ( ) = = CONTROL_END )
controlParentAfter = controlParentAfter - > controlParent ( ) ;
while ( insertBefore - > lexPrev ( ) - > variant ( ) = = DVM_PARALLEL_ON_DIR | | insertBefore - > lexPrev ( ) - > variant ( ) = = DVM_REDISTRIBUTE_DIR )
insertBefore = insertBefore - > lexPrev ( ) ;
while ( insertAfter - > lexPrev ( ) - > variant ( ) = = DVM_PARALLEL_ON_DIR )
insertAfter = insertAfter - > lexPrev ( ) ;
while ( insertAfter - > lexNext ( ) - > variant ( ) = = DVM_REDISTRIBUTE_DIR )
insertAfter = insertAfter - > lexNext ( ) ;
while ( insertBefore & & isSgExecutableStatement ( insertBefore ) = = NULL )
insertBefore = insertBefore - > lexNext ( ) ;
for ( int k = 0 ; k < reDistrRulesBefore . size ( ) ; + + k )
insertBefore - > insertStmtBefore ( reDistrRulesBefore [ k ] - > copy ( ) , * insertBefore - > controlParent ( ) ) ;
for ( int k = 0 ; k < reDistrRulesAfter . size ( ) ; + + k )
insertAfter - > insertStmtAfter ( reDistrRulesAfter [ k ] - > copy ( ) , * controlParentAfter ) ;
for ( int k = 0 ; k < reAlignRules . size ( ) ; + + k )
insertBefore - > insertStmtBefore ( reAlignRules [ k ] - > copy ( ) , * insertBefore - > controlParent ( ) ) ;
// insert redistribute before all return stats
for ( SgStatement * st = ( * currLines ) [ i ] . stats . first ; st - > variant ( ) ! = SPF_END_PARALLEL_REG_DIR ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = RETURN_STAT )
{
SgStatement * cp = st - > controlParent ( ) ;
if ( cp - > variant ( ) = = LOGIF_NODE )
cp = ( ( SgLogIfStmt * ) cp ) - > convertLogicIf ( ) ;
for ( int k = 0 ; k < reDistrRulesBefore . size ( ) ; + + k )
st - > insertStmtBefore ( reDistrRulesAfter [ k ] - > copy ( ) , * cp ) ;
}
}
SgStatement * module = ( * currLines ) [ i ] . stats . first ;
int modVar = module - > variant ( ) ;
while ( modVar ! = MODULE_STMT & & modVar ! = FUNC_HEDR & & modVar ! = PROC_HEDR & & modVar ! = PROG_HEDR )
{
module = module - > controlParent ( ) ;
modVar = module - > variant ( ) ;
}
map < int , vector < int > > allLabRefs ;
findAllRefsToLables ( module , allLabRefs ) ;
int labNum = 1 ;
// insert redistribute after all entry points
for ( SgStatement * st = ( * currLines ) [ i ] . stats . first - > lexNext ( ) ; st - > variant ( ) ! = SPF_END_PARALLEL_REG_DIR ; st = st - > lexNext ( ) )
{
if ( st - > variant ( ) = = ENTRY_STAT )
{
SgStatement * cp = st - > controlParent ( ) ;
SgStatement * afterEntry = st - > lexNext ( ) ;
int goToLab = - 1 ;
SgLabel * goToLabp = NULL ;
if ( afterEntry - > label ( ) )
{
goToLabp = afterEntry - > label ( ) ;
goToLab = goToLabp - > getLabNumber ( ) ;
}
else
{
while ( allLabRefs . find ( labNum ) ! = allLabRefs . end ( ) )
+ + labNum ;
goToLab = labNum ;
allLabRefs . insert ( make_pair ( labNum , vector < int > ( ) ) ) ;
+ + labNum ;
goToLabp = new SgLabel ( goToLab ) ;
afterEntry - > setLabel ( * goToLabp ) ;
BIF_LABEL_USE ( afterEntry - > thebif ) = goToLabp - > thelabel ;
}
SgGotoStmt * gotoStat = new SgGotoStmt ( * goToLabp ) ;
st - > insertStmtBefore ( * gotoStat , * cp ) ;
for ( int k = 0 ; k < reAlignRules . size ( ) ; + + k )
st - > insertStmtAfter ( reAlignRules [ k ] - > copy ( ) , * cp ) ;
for ( int k = 0 ; k < reDistrRulesBefore . size ( ) ; + + k )
st - > insertStmtAfter ( reDistrRulesBefore [ k ] - > copy ( ) , * cp ) ;
}
}
}
}
2024-03-24 21:24:32 +03:00
}
void insertParallelDirs ( SgFile * file , bool extract ,
vector < Directive * > & createdDirectives ,
vector < Messages > & messages ,
map < string , string > & templateDeclInIncludes ,
map < string , map < int , set < string > > > & commentsToInclude ,
const vector < FuncInfo * > & callGraph ,
const vector < ParallelRegion * > & parallelRegions ,
const map < string , vector < LoopGraph * > > & loopGraph ,
const set < string > & allFileNames ,
const map < DIST : : Array * , set < DIST : : Array * > > & arrayLinksByFuncCalls ,
const map < tuple < int , string , string > , pair < DIST : : Array * , DIST : : ArrayAccessInfo * > > & declaredArrays ,
const map < DIST : : Array * , tuple < int , string , string > > & tableOfUniqNamesByArray )
{
const char * file_name = file - > filename ( ) ;
insertDirectiveToFile ( file , file_name , createdDirectives , extract , messages ) ;
2024-06-19 18:08:27 +03:00
if ( sharedMemoryParallelization = = 0 )
2024-03-24 21:24:32 +03:00
{
map < string , FuncInfo * > mapFuncInfo ;
createMapOfFunc ( callGraph , mapFuncInfo ) ;
for ( int z = 0 ; z < parallelRegions . size ( ) ; + + z )
{
ParallelRegion * currReg = parallelRegions [ z ] ;
const DataDirective & dataDirectives = currReg - > GetDataDir ( ) ;
const vector < int > & currentVariant = currReg - > GetCurrentVariant ( ) ;
const DIST : : Arrays < int > & allArrays = currReg - > GetAllArrays ( ) ;
DIST : : GraphCSR < int , double , attrType > & reducedG = currReg - > GetReducedGraphToModify ( ) ;
const set < string > distrArrays = fillDistributedArrays ( dataDirectives , tableOfUniqNamesByArray , arrayLinksByFuncCalls ) ;
const vector < string > distrRules = dataDirectives . GenRule ( currentVariant ) ;
const vector < vector < dist > > distrRulesSt = dataDirectives . GenRule ( currentVariant , 0 ) ;
const vector < string > alignRules = dataDirectives . GenAlignsRules ( ) ;
insertDistributionToFile ( file , file_name , dataDirectives , distrArrays , distrRules , distrRulesSt , alignRules , loopGraph ,
allArrays , reducedG , commentsToInclude , templateDeclInIncludes , extract , messages ,
arrayLinksByFuncCalls , mapFuncInfo , currReg - > GetId ( ) , allFileNames ) ;
insertLoopTempalteDeclaration ( file , dataDirectives , distrRules , distrRulesSt , allArrays , extract , currReg - > GetId ( ) ) ;
}
}
if ( extract )
{
createdDirectives . clear ( ) ;
//clear shadow specs
for ( auto & array : declaredArrays )
array . second . first - > ClearShadowSpecs ( ) ;
}
2024-06-19 18:08:27 +03:00
else if ( sharedMemoryParallelization = = 0 )
2024-03-24 21:24:32 +03:00
{
set < uint64_t > regNum ;
for ( int z = 0 ; z < parallelRegions . size ( ) ; + + z )
regNum . insert ( parallelRegions [ z ] - > GetId ( ) ) ;
insertTemplateModuleUse ( file , regNum , arrayLinksByFuncCalls ) ;
}
2023-09-14 19:43:13 +03:00
}