diff --git a/dvm/fdvm/trunk/fdvm/acc.cpp b/dvm/fdvm/trunk/fdvm/acc.cpp index 143323c..995a215 100644 --- a/dvm/fdvm/trunk/fdvm/acc.cpp +++ b/dvm/fdvm/trunk/fdvm/acc.cpp @@ -655,6 +655,26 @@ SgSymbol *HostProcSymbol(SgStatement *st_do) return(s); } +SgSymbol *HostAcrossProcSymbol(SgSymbol *sHostProc, int dependency) +{ + SgSymbol *s; + char *sname = (char *)malloc((unsigned)(strlen(sHostProc->identifier())) + 5); + sprintf(sname, "%s_%d", sHostProc->identifier(), dependency); + s = new SgSymbol(PROCEDURE_NAME, sname, *current_file->firstStatement()); + acc_func_list = AddToSymbList(acc_func_list, s); + return(s); +} + +SgSymbol *HostProcSymbol_RA(SgSymbol *sHostProc) +{ + SgSymbol *s; + char *sname = (char *)malloc((unsigned)(strlen(sHostProc->identifier())) + 4); + sprintf(sname, "%s_%s", sHostProc->identifier(), "RA"); + s = new SgSymbol(PROCEDURE_NAME, sname, *current_file->firstStatement()); + acc_func_list = AddToSymbList(acc_func_list, s); + return(s); +} + SgSymbol *IndirectFunctionSymbol(SgStatement *stmt, char *name) { char *sname = (char *)malloc((unsigned)(strlen(stmt->fileName())) + 40); @@ -675,15 +695,6 @@ SgSymbol *GPUModuleSymb(SgStatement *global_st) return(mod_symb); } -SgSymbol *HostAcrossProcSymbol(SgSymbol *sHostProc, int dependency) -{ - SgSymbol *s; - char *sname = (char *)malloc((unsigned)(strlen(sHostProc->identifier())) + 5); - sprintf(sname, "%s_%d", sHostProc->identifier(), dependency); - s = new SgSymbol(PROCEDURE_NAME, sname, *current_file->firstStatement()); - acc_func_list = AddToSymbList(acc_func_list, s); - return(s); -} SgSymbol *CudaforSymb(SgStatement *global_st) { @@ -2545,7 +2556,7 @@ void ACC_ParallelLoopEnd(SgStatement *pardo) // creating host-handler for loop anyway if (!WithAcrossClause()) - Create_Host_Loop_Subroutine(hostproc_symb, 0); + Create_Host_Loop_Subroutine_Main(hostproc_symb); else { Create_Host_Across_Loop_Subroutine(hostproc_symb); @@ -2714,8 +2725,8 @@ void ACC_CreateParallelLoop(int ipl, SgStatement *first_do, int nloop, SgStateme number_of_loop_line = first_do->lineNumber(); // creating buffers for remote_access references (after creating GPU module) - if (rma && !rma->rmout && !rma->rml->symbol()) // there is synchronous REMOTE_ACCESS clause in PARALLEL directive - CreateRemoteAccessBuffers(); + //if (rma && !rma->rmout && !rma->rml->symbol()) // there is synchronous REMOTE_ACCESS clause in PARALLEL directive + CreateRemoteAccessBuffersUp(); if (cur_region) { // is first loop of compute region @@ -2785,7 +2796,7 @@ SgStatement *ACC_CreateStatementGroup(SgStatement *first_st) // Generating statements for block (sequence) in source program unit cur_st = first_st->lexPrev();//last_st; //doStatementsInSourceProgramUnit(first_st, 0, NULL, NULL, adapter_symb, hostproc_symb, 0, NULL, NULL, NULL, NULL); - doStatementsToPerformByHandler(CreateLoopForSequence(first_st),adapter_symb, hostproc_symb, 0, 1); + doStatementsToPerformByHandler(CreateLoopForSequence(first_st),adapter_symb, hostproc_symb, 0, parloop_by_handler); st_end = cur_st; // --------------------------------------------------- if ((cur_region->targets & CUDA_DEVICE)) //if(targets[CUDA]) @@ -3238,12 +3249,13 @@ void ACC_ReductionVarsAreActual() } } -void CreateRemoteAccessBuffers() +void CreateRemoteAccessBuffers(SgExpression *rml, int pl_flag) { SgExpression *el; rem_var *remv; coeffs *scoef; - for (el = rma->rml; el; el = el->rhs()) + int interface = parloop_by_handler == 2 && WhatInterface(dvm_parallel_dir) == 2 ? 2 : 1; + for (el = rml; el; el = el->rhs()) { remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); if(!remv) continue; // error case: illegal reference in REMOTE_ACCESS directive/clause @@ -3254,10 +3266,28 @@ void CreateRemoteAccessBuffers() // scoef = BufferCoeffs(remv->buffer,el->lhs()->symbol()); // adding the attribute (ARRAY_COEF) to buffer symbol remv->buffer->addAttribute(ARRAY_COEF, (void*)scoef, sizeof(coeffs)); + if (pl_flag && interface == 2) + remv->buffer->addAttribute(REMOTE_ACCESS_BUF, (void*)1, 0); } return; } +void CreateRemoteAccessBuffersUp() +{ + rem_acc *r; + //looking through the remote-access directive/clause list + for (r=rma; r; r=r->next) + { + //if (r->rml->symbol()) // asynchronous REMOTE_ACCESS clause/directive + // continue; + if (!r->rmout) // REMOTE_ACCESS clause in PARALLEL directive + CreateRemoteAccessBuffers(r->rml, 1); + else + CreateRemoteAccessBuffers(r->rml, 0); + } + return; +} + SgSymbol *CreateReplicatedArray(SgSymbol *s) { SgSymbol *ar; @@ -3508,16 +3538,19 @@ SgExpression *RemoteAccessHeaderList() { SgExpression *el, *l, *rma_list; rem_var *remv; + rem_acc *r; rma_list = NULL; - if (rma && !rma->rmout && !rma->rml->symbol()) // there is synchronous REMOTE_ACCESS clause in PARALLEL directive - for (el = rma->rml; el; el = el->rhs()) + for (r=rma; r; r=r->next) { - remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); - if(!remv) continue; // error case: illegal reference in REMOTE_ACCESS directive/clause - l = new SgExprListExp(*DVM000(remv->index)); - l->setRhs(rma_list); - rma_list = l; - //rma_list = AddListToList(rma_list, l ); + for (el = r->rml; el; el = el->rhs()) + { + remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); + if(!remv) continue; // error case: illegal reference in REMOTE_ACCESS directive/clause + l = new SgExprListExp(*DVM000(remv->index)); + l->setRhs(rma_list); + rma_list = l; + //rma_list = AddListToList(rma_list, l ); + } } return(rma_list); } @@ -3526,13 +3559,21 @@ void AddRemoteAccessBufferList_ToArrayList() { SgExpression *el; rem_var *remv; - if (rma && !rma->rmout && !rma->rml->symbol()) // there is synchronous REMOTE_ACCESS clause in PARALLEL directive - for (el = rma->rml; el; el = el->rhs()) + rem_acc *r; + //looking through the remote-access directive/clause list + for (r=rma; r; r=r->next) { - remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); - if(!remv) continue; // error case: illegal reference in REMOTE_ACCESS directive/clause - acc_array_list = AddNewToSymbList(acc_array_list, remv->buffer); + //if (r->rml->symbol()) // asynchronous REMOTE_ACCESS clause/directive + // continue; + for (el = r->rml; el; el = el->rhs()) + { + remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); + if (remv && remv->buffer) + acc_array_list = AddNewToSymbList(acc_array_list, remv->buffer); + } + } + return; } @@ -3570,13 +3611,15 @@ SgExpression *BaseArgumentList() { symb_list *sl, *array_list; SgExpression *el, *l, *base_list = NULL; + rem_acc *r; // create memory base list array_list = NULL; // create remote_access objects list - if (rma && !rma->rmout && !rma->rml->symbol()) // there is synchronous REMOTE_ACCESS clause in PARALLEL directive - for (el = rma->rml; el; el = el->rhs()) - array_list = AddToSymbList(array_list, el->lhs()->symbol()); - + for (r=rma; r; r=r->next) + { + for (el = r->rml; el; el = el->rhs()) + array_list = AddToSymbList(array_list, el->lhs()->symbol()); + } if (array_list) { base_list = ElementOfBaseList(NULL, array_list->symb); @@ -3633,7 +3676,7 @@ SgExpression *AddrArgumentList() symb_list *sl; SgExpression *el, *l, *addr_list = NULL, *ae, *rem_list = NULL; rem_var *remv; - + rem_acc *r; // create array address list if (acc_array_list) { @@ -3647,17 +3690,25 @@ SgExpression *AddrArgumentList() } } // create remote_access buffer address list and add it to addr_list - if (rma && !rma->rmout && !rma->rml->symbol()) // there is synchronous REMOTE_ACCESS clause in PARALLEL directive - for (el = rma->rml; el; el = el->rhs()) + + //looking through the remote-access directive/clause list + for (r=rma; r; r=r->next) { - remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); - if(!remv) continue; // error case: illegal reference in REMOTE_ACCESS directive/clause - ae = DVM000(remv->index + remv->ncolon + 1); - l = new SgExprListExp(*new SgArrayRefExp(*baseMemory(el->lhs()->symbol()->type()->baseType()), *ae)); - l->setRhs(rem_list); - rem_list = l; + for (el = r->rml; el; el = el->rhs()) + { + remv = (rem_var *)(el->lhs())->attributeValue(0, REMOTE_VARIABLE); + if(!remv) continue; // error case: illegal reference in REMOTE_ACCESS directive/clause + if (IS_REMOTE_ACCESS_BUFFER(remv->buffer) ) + l = new SgExprListExp(*new SgArrayRefExp(*baseMemory(el->lhs()->symbol()->type()->baseType()))); + else + { + ae = DVM000(remv->index + remv->ncolon + 1); + l = new SgExprListExp(*new SgArrayRefExp(*baseMemory(el->lhs()->symbol()->type()->baseType()), *ae)); + } + l->setRhs(rem_list); + rem_list = l; + } } - addr_list = AddListToList(rem_list, addr_list); return(addr_list); } @@ -5523,12 +5574,12 @@ SgStatement *Create_Host_Across_Loop_Subroutine(SgSymbol *sHostProc) { SgStatement *stmt = NULL, *st_end = NULL, *st_hedr = NULL, *cur = NULL, *last_decl = NULL; SgExpression *ae = NULL, *arg_list = NULL, *el = NULL, *de = NULL, *tail = NULL, *baseMem_list = NULL; - SgSymbol *s_loop_ref = NULL, *sarg = NULL, *h_first = NULL, *hl = NULL; + SgSymbol *s_loop_ref = NULL, *sarg = NULL, *h_first = NULL, *h_last = NULL,*hl = NULL; symb_list *sl = NULL; SgType *tdvm = NULL; - int ln; + int ln, nbuf = 0; char *name = NULL; - + SgExprListExp *list = isSgExprListExp(dvm_parallel_dir->expr(2)); // do_variables list SgSymbol *sHostAcrossProc; symb_list *acc_acr_call_list = NULL; @@ -5568,14 +5619,20 @@ SgStatement *Create_Host_Across_Loop_Subroutine(SgSymbol *sHostProc) if (!ln) h_first = sarg; } - + h_last = sarg; // add dvm-array-address list if (options.isOn(O_HOST)) { tail = arg_list; for (sl = acc_array_list, hl = h_first; sl; sl = sl->next, hl = hl->next()) { - sarg = DummyDvmArraySymbol(sl->symb, hl); + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + { + sarg = DummyDvmBufferSymbol(sl->symb, hl); + nbuf++; + } + else + sarg = DummyDvmArraySymbol(sl->symb, hl); ae = new SgArrayRefExp(*sarg); arg_list->setRhs(*new SgExprListExp(*ae)); arg_list = arg_list->rhs(); @@ -5666,6 +5723,33 @@ SgStatement *Create_Host_Across_Loop_Subroutine(SgSymbol *sHostProc) //stmt = PrintStat(which_run_expr); //st_end->insertStmtBefore(*stmt, *st_hedr); + // create argument list of handler's call + SgExpression *new_arg_list = &st_hedr->expr(0)->copy(); + if (nbuf > 0) // there is REMOTE_ACCESS clause and RTS2 interface is used + // correct argument list of handler's call + { + el = new_arg_list->rhs(); + while(el->lhs()->symbol() != h_last->next()) + el = el->rhs(); + for (sl = acc_array_list, hl = h_first; sl; sl = sl->next, hl = hl->next(), el = el->rhs()) + { + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) + { + // correct argument: buffer => buffer(buf_header(Rank+2)) + SgArrayRefExp *buf_ref = new SgArrayRefExp(*hl,*new SgValueExp(Rank(sl->symb)+2)); + el->lhs()->setLhs(*new SgExprListExp(*buf_ref)); + // generate call statements of 'dvmh_loop_get_remote_buf' for remote access buffers + stmt = GetRemoteBuf(s_loop_ref, nbuf--, hl); + last_decl->insertStmtAfter(*stmt, *st_hedr); + } + } + // create external statement + stmt = new SgStatement(EXTERN_STAT); + el = new SgExprListExp(*new SgVarRefExp(fdvm[GET_REMOTE_BUF])); + stmt->setExpression(0, *el); + last_decl->insertStmtAfter(*stmt, *st_hedr); + } + SgIfStmt *ifstmt = NULL; SgStatement *falsestmt = NULL; int i = 0; @@ -5678,12 +5762,12 @@ SgStatement *Create_Host_Across_Loop_Subroutine(SgSymbol *sHostProc) fbtest->addArg(*new SgValueExp(i - 1)); if (i != 0) { - SgCallStmt *truestmt = new SgCallStmt(*sl->symb, *st_hedr->expr(0)); + SgCallStmt *truestmt = new SgCallStmt(*sl->symb, *new_arg_list); ifstmt = new SgIfStmt(*fbtest, *truestmt, *falsestmt); falsestmt = ifstmt; } else { - falsestmt = new SgCallStmt(*sl->symb, *st_hedr->expr(0)); + falsestmt = new SgCallStmt(*sl->symb, *new_arg_list); } i++; } @@ -5692,6 +5776,148 @@ SgStatement *Create_Host_Across_Loop_Subroutine(SgSymbol *sHostProc) return(st_hedr); } +SgStatement *Create_Host_Loop_Subroutine_Main (SgSymbol *sHostProc) +{ + SgStatement *stmt = NULL, *st_end = NULL, *st_hedr = NULL, *last_decl = NULL; + SgExpression *ae, *arg_list = NULL, *el = NULL, *de = NULL, *tail = NULL, *baseMem_list = NULL; + SgSymbol *s_loop_ref = NULL, *sarg = NULL, *h_first = NULL, *h_last = NULL, *hl = NULL, *bl = NULL; + SgSymbol *s = NULL; + symb_list *sl = NULL; + int ln, nbuf = 0; + SgSymbol *sHostProc_RA; + + if(rma && !rma->rmout && !rma->rml->symbol() && parloop_by_handler == 2 && WhatInterface(dvm_parallel_dir) == 2 )// there is synchronous REMOTE_ACCESS clause in PARALLEL directive and RTS2 interface is used + // create additional procedure for creating headers of remote access buffers + { + sHostProc_RA = HostProcSymbol_RA(sHostProc); + Create_Host_Loop_Subroutine (sHostProc_RA, 0); + } + else + return (Create_Host_Loop_Subroutine (sHostProc, 0)); + + // create Host procedure header and end for subroutine named by sHostProc + + st_hedr = CreateHostProcedure(sHostProc); + st_hedr->addComment(Host_LoopHandlerComment()); + st_end = st_hedr->lexNext(); + + // create dummy argument list + // loop_ref,,, + + s_loop_ref = new SgSymbol(VARIABLE_NAME, "loop_ref", *FortranDvmType(), *st_hedr); + + ae = new SgVarRefExp(s_loop_ref); + arg_list = new SgExprListExp(*ae); + st_hedr->setExpression(0, *arg_list); + + // add dvm-array-header list + for (sl = acc_array_list, ln = 0; sl; sl = sl->next, ln++) + { + sarg = DummyDvmHeaderSymbol(sl->symb,st_hedr); + ae = new SgArrayRefExp(*sarg); + arg_list->setRhs(*new SgExprListExp(*ae)); + arg_list = arg_list->rhs(); + if (!ln) + h_first = sarg; + } + h_last = sarg; + + // add dvm-array-address list + if (options.isOn(O_HOST)) + { + tail = arg_list; + for (sl = acc_array_list, hl = h_first; sl; sl = sl->next, hl = hl->next()) + { + if(IS_REMOTE_ACCESS_BUFFER(sl->symb)) + { + sarg = DummyDvmBufferSymbol(sl->symb, hl); + nbuf++; + } + else + sarg = DummyDvmArraySymbol(sl->symb, hl); + ae = new SgArrayRefExp(*sarg); + arg_list->setRhs(*new SgExprListExp(*ae)); + arg_list = arg_list->rhs(); + } + tail = tail->rhs(); + } + else + // create memory base list and add it to the dummy argument list + { + baseMem_list = tail = CreateBaseMemoryList(); + AddListToList(arg_list, baseMem_list); + } + + // add use's list to dummy argument list + if (uses_list) + { + AddListToList(arg_list, copy_uses_list = &(uses_list->copy())); + if (!tail) + tail = copy_uses_list; + } + if(red_list) + { + SgExpression * red_bound_list; + AddListToList(arg_list, red_bound_list = DummyListForReductionArrays(st_hedr)); + if(!tail) + tail = red_bound_list; + } + + // create external statement + stmt = new SgStatement(EXTERN_STAT); + el = new SgExprListExp(*new SgVarRefExp(fdvm[GET_REMOTE_BUF])); + el->setRhs(*new SgExprListExp(*new SgVarRefExp(sHostProc_RA))); + stmt->setExpression(0, *el); + st_hedr->insertStmtAfter(*stmt, *st_hedr); + + last_decl = stmt; + + // create dummy argument declarations + + for (el = tail; el; el = el->rhs()) + { + stmt = el->lhs()->symbol()->makeVarDeclStmt(); + ConstantSubstitutionInTypeSpec(stmt->expr(1)); + st_hedr->insertStmtAfter(*stmt, *st_hedr); + } + + el = st_hedr->expr(0); + stmt = el->lhs()->symbol()->makeVarDeclStmt(); + st_hedr->insertStmtAfter(*stmt, *st_hedr); + de = stmt->expr(0); + + for (el = el->rhs(); el != tail; el = el->rhs()) + { //printf("%s \n",el->lhs()->symbol()->identifier()); + de->setRhs(new SgExprListExp(*el->lhs()->symbol()->makeDeclExpr())); + de = de->rhs(); + } + + // generate IMPLICIT NONE statement + st_hedr->insertStmtAfter(*new SgStatement(IMPL_DECL), *st_hedr); + + // generate handler call + stmt = new SgCallStmt(*sHostProc_RA, (st_hedr->expr(0))->copy()); + last_decl->insertStmtAfter(*stmt, *st_hedr); + el = stmt->expr(0)->rhs(); + // correct argument list of handler call + while(el->lhs()->symbol() != h_last->next()) + el = el->rhs(); + for (sl = acc_array_list, hl = h_first; sl; sl = sl->next, hl = hl->next(), el = el->rhs()) + { + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) + { + // correct argument: buffer => buffer(buf_header(Rank+2)) + SgArrayRefExp *buf_ref = new SgArrayRefExp(*hl,*new SgValueExp(Rank(sl->symb)+2)); + el->lhs()->setLhs(*new SgExprListExp(*buf_ref)); + // generate call statements of 'dvmh_loop_get_remote_buf' for remote access buffers + stmt = GetRemoteBuf(s_loop_ref, nbuf--, hl); + last_decl->insertStmtAfter(*stmt, *st_hedr); + } + } + + return (st_hedr); +} + SgStatement *Create_Host_Loop_Subroutine(SgSymbol *sHostProc, int dependency) { SgStatement *stmt = NULL, *st_end = NULL, *st_hedr = NULL, *cur = NULL, *last_decl = NULL, *ass = NULL; @@ -5714,7 +5940,6 @@ SgStatement *Create_Host_Loop_Subroutine(SgSymbol *sHostProc, int dependency) addopenmp = 1; /* OpenMP */ // create Host procedure header and end - st_hedr = CreateHostProcedure(sHostProc); st_hedr->addComment(Host_LoopHandlerComment()); st_end = st_hedr->lexNext(); @@ -6866,6 +7091,13 @@ SgSymbol *DummyDvmArraySymbol(SgSymbol *ar, SgSymbol *header_symb) return(new SgSymbol(VARIABLE_NAME, ar->identifier(), *typearray, *header_symb->scope())); } +SgSymbol *DummyDvmBufferSymbol(SgSymbol *ar, SgSymbol *header_symb) +{ + SgArrayType *typearray = new SgArrayType(*ar->type()->baseType()); + typearray->addRange(*Dimension(header_symb, 1, 1)); + return(new SgSymbol(VARIABLE_NAME, ar->identifier(), *typearray, *header_symb->scope())); +} + SgExpression *Dimension(SgSymbol *hs, int i, int rank) { SgValueExp M0(0), M1(1); @@ -12762,7 +12994,7 @@ SgStatement *Create_C_Adapter_Function(SgSymbol *sadapter, int InternalPosition) SgStatement *Create_C_Adapter_Function(SgSymbol *sadapter) { symb_list *sl; - SgStatement *st_hedr, *st_end, *stmt, *do_while, *first_exec, *st_base = NULL, *st_call; + SgStatement *st_hedr, *st_end, *stmt, *do_while, *first_exec, *st_base = NULL, *st_call, *cur; SgExpression *fe, *ae, *arg_list, *el, *e, *er; SgExpression *espec; SgFunctionCallExp *fcall; @@ -12773,11 +13005,11 @@ SgStatement *Create_C_Adapter_Function(SgSymbol *sadapter) SgSymbol *s_num_of_red_blocks = NULL, *s_fill_flag = NULL, *s_red_num = NULL, *s_restBlocks = NULL, *s_addBlocks = NULL, *s_overallBlocks = NULL; SgSymbol *s_max_blocks; SgType *typ = NULL; - int ln, num, i, uses_num, shared_mem_count, has_red_array, use_device_num; + int ln, num, i, uses_num, shared_mem_count, has_red_array, use_device_num, nbuf; char *define_name; int pl_rank = ParLoopRank(); h_first = hgpu_first = base_first = red_first = uses_first = scalar_first = NULL; - has_red_array = 0; use_device_num = 0; + has_red_array = 0; use_device_num = 0; nbuf = 0; s_dev_num = NULL; s_shared_mem = NULL; @@ -12814,6 +13046,8 @@ SgStatement *Create_C_Adapter_Function(SgSymbol *sadapter) arg_list = arg_list->rhs(); if (!ln) h_first = sarg; + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + nbuf++; } for (el = uses_list, ln = 0; el; el = el->rhs(), ln++) // uses { @@ -13101,12 +13335,18 @@ SgStatement *Create_C_Adapter_Function(SgSymbol *sadapter) /* -------- call dvmh_get_natural_base(long *deviceRef, long dvmDesc[] ) ----*/ - for (s = h_first, sb = base_first, ln = 0; ln < num; s = s->next(), sb = sb->next(), ln++) + for (sl = acc_array_list, s = h_first, sb = base_first, ln = 0; ln < num; sl = sl->next, s = s->next(), sb = sb->next(), ln++) { s_dev_num = doDeviceNumVar(st_hedr, first_exec, s_dev_num, s_loop_ref); e = &SgAssignOp(*new SgVarRefExp(sb), *GetNaturalBase(s_dev_num, s)); - stmt = new SgCExpStmt(*e); + stmt = cur = new SgCExpStmt(*e); st_end->insertStmtBefore(*stmt, *st_hedr); + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + { + e = LoopGetRemoteBuf(s_loop_ref, nbuf--, s); + stmt = new SgCExpStmt(*e); + cur->insertStmtBefore(*stmt, *st_hedr); + } if (!ln) { stmt->addComment("// Get 'natural' bases"); diff --git a/dvm/fdvm/trunk/fdvm/acc_across.cpp b/dvm/fdvm/trunk/fdvm/acc_across.cpp index 279fa0e..76af6ff 100644 --- a/dvm/fdvm/trunk/fdvm/acc_across.cpp +++ b/dvm/fdvm/trunk/fdvm/acc_across.cpp @@ -1125,7 +1125,7 @@ vector Create_C_Adapter_Function_Across_OneThread(SgSymbol *sadap SgType *typ; SgFunctionCallExp *funcCall; vector dvm_array_headers; - int ln, num, uses_num, has_red_array, use_device_num, num_of_red_arrays = 0; + int ln, num, uses_num, has_red_array, use_device_num, num_of_red_arrays = 0, nbuf = 0; // init block reduction_ptr = NULL; @@ -1176,6 +1176,8 @@ vector Create_C_Adapter_Function_Across_OneThread(SgSymbol *sadap arg_list = arg_list->rhs(); if (!ln) h_first = sarg; + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + nbuf++; } for (el = uses_list, ln = 0; el; el = el->rhs(), ++ln) // @@ -1394,12 +1396,19 @@ vector Create_C_Adapter_Function_Across_OneThread(SgSymbol *sadap /* -------- call dvmh_get_natural_base(long *deviceRef, long dvmDesc[] ) ----*/ - for (s = h_first, sb = base_first, ln = 0; ln < num; s = s->next(), sb = sb->next(), ln++) + for (sl = acc_array_list, s = h_first, sb = base_first, ln = 0; ln < num; sl = sl->next, s = s->next(), sb = sb->next(), ln++) { s_dev_num = doDeviceNumVar(st_hedr, first_exec, s_dev_num, s_loop_ref); e = &SgAssignOp(*new SgVarRefExp(sb), *GetNaturalBase(s_dev_num, s)); stmt = new SgCExpStmt(*e); + SgStatement *cur = stmt; st_end->insertStmtBefore(*stmt, *st_hedr); + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + { + e = LoopGetRemoteBuf(s_loop_ref, nbuf--, s); + stmt = new SgCExpStmt(*e); + cur->insertStmtBefore(*stmt, *st_hedr); + } if (!ln) stmt->addComment("// Get natural bases"); } @@ -1754,7 +1763,7 @@ vector Create_C_Adapter_Function_Across_variants(SgSymbol *sadapt SgType *typ; SgFunctionCallExp *funcCall, *funcCallKernel; vector dvm_array_headers; - int ln, num, uses_num, has_red_array, use_device_num, num_of_red_arrays; + int ln, num, uses_num, has_red_array, use_device_num, num_of_red_arrays, nbuf = 0; // init block lowI = highI = idxI = elem = red_blocks = shared_mem = stream_t = bIdxs = NULL; @@ -1812,6 +1821,8 @@ vector Create_C_Adapter_Function_Across_variants(SgSymbol *sadapt arg_list = arg_list->rhs(); if (!ln) h_first = sarg; + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + nbuf++; } for (el = uses_list, ln = 0; el; el = el->rhs(), ++ln) // @@ -2297,12 +2308,19 @@ vector Create_C_Adapter_Function_Across_variants(SgSymbol *sadapt /* -------- call dvmh_get_natural_base(long *deviceRef, long dvmDesc[] ) ----*/ - for (s = h_first, sb = base_first, ln = 0; ln < num; s = s->next(), sb = sb->next(), ln++) + for (sl = acc_array_list, s = h_first, sb = base_first, ln = 0; ln < num; sl = sl->next, s = s->next(), sb = sb->next(), ln++) { s_dev_num = doDeviceNumVar(st_hedr, first_exec, s_dev_num, s_loop_ref); e = &SgAssignOp(*new SgVarRefExp(sb), *GetNaturalBase(s_dev_num, s)); stmt = new SgCExpStmt(*e); + SgStatement *cur = stmt; st_end->insertStmtBefore(*stmt, *st_hedr); + if (IS_REMOTE_ACCESS_BUFFER(sl->symb)) // case of RTS2 interface + { + e = LoopGetRemoteBuf(s_loop_ref, nbuf--, s); + stmt = new SgCExpStmt(*e); + cur->insertStmtBefore(*stmt, *st_hedr); + } if (!ln) stmt->addComment("// Get natural bases"); } diff --git a/dvm/fdvm/trunk/fdvm/dvm.cpp b/dvm/fdvm/trunk/fdvm/dvm.cpp index debdf1d..5087bd0 100644 --- a/dvm/fdvm/trunk/fdvm/dvm.cpp +++ b/dvm/fdvm/trunk/fdvm/dvm.cpp @@ -9683,6 +9683,21 @@ void RemoteAccessDirective(SgStatement *stmt) RemoteVariableList(stmt->symbol(),stmt->expr(0),stmt); } +SgExpression *AlignmentListForRemoteDir(int nt, SgExpression *axis[], SgExpression *coef[], SgExpression *cons[]) +{ // case of RTS2 interface + SgExpression *arglist=NULL, *el, *e; + + for(int i=0; isetRhs(arglist); + arglist = el; + } + (el = new SgExprListExp(*ConstRef(nt)))->setRhs(arglist); // add rank to axis list + arglist = el; + return arglist; +} + void RemoteVariableList1(SgSymbol *group,SgExpression *rml, SgStatement *stmt) { SgStatement *if_st,*end_st = NULL; SgExpression *el, *es; @@ -9751,7 +9766,10 @@ void RemoteVariableList(SgSymbol *group, SgExpression *rml, SgStatement *stmt) return; if(IN_COMPUTE_REGION && group) err("Asynchronous REMOTE_ACCESS clause in compute region",574,stmt); - + if(group && parloop_by_handler == 2 && stmt->variant() != DVM_PARALLEL_ON_DIR ) { // case of REMOTE_ACCESS directive + err("Illegal directive in -Opl2 mode. Asynchronous operations are not supported in this mode", 649, stmt); + group = NULL; + } if(group){ if_st = doIfThenConstrForRemAcc(group,cur_st); end_st = cur_st; //END IF @@ -9824,7 +9842,7 @@ void RemoteVariableList(SgSymbol *group, SgExpression *rml, SgStatement *stmt) } else { axis[n] = &c0.copy(); coef[n] = &c0.copy(); - cons[n] = &(es->lhs()->copy() - *Exprn( LowerBound(el->lhs()->symbol(),n))) ; + cons[n] = parloop_by_handler == 2 ? &es->lhs()->copy() : &(es->lhs()->copy() - *Exprn( LowerBound(el->lhs()->symbol(),n))) ; ind_deb[n] = &(cons[n]->copy()); //init[n] = &c0.copy(); //last[n] = &c0.copy(); @@ -9869,6 +9887,22 @@ void RemoteVariableList(SgSymbol *group, SgExpression *rml, SgStatement *stmt) //buffer_head = DVM000(ibuf); ar = NULL; } + // adding attribute REMOTE_VARIABLE + rem_var *remv = new rem_var; + remv->ncolon = nc; + remv->index = ibuf; + remv->amv = group ? 1 : iamv; + remv->buffer = NULL; /*ACC*/ + + (el->lhs())->addAttribute(REMOTE_VARIABLE,(void *) remv, sizeof(rem_var)); + + // case of RTS2-interface + if(parloop_by_handler==2) { + if(stmt->variant() != DVM_PARALLEL_ON_DIR) { + doCallAfter(RemoteAccess_H2(header_rf(ar,ibuf,1), el->lhs()->symbol(), HeaderRef(el->lhs()->symbol()), AlignmentListForRemoteDir(n,axis,coef,cons))); + } + continue; + } // creating buffer for remote elements of array iaxis = ndvm; if (stmt->variant() == DVM_PARALLEL_ON_DIR) { @@ -9920,17 +9954,9 @@ void RemoteVariableList(SgSymbol *group, SgExpression *rml, SgStatement *stmt) } InsertNewStatementAfter(D_RmBuf( HeaderRef(el->lhs()->symbol()),GetAddresDVM( header_rf(ar,ibuf,1)),n,ideb),cur_st,cur_st->controlParent()); } - SET_DVM(iaxis); - //adding attribute REMOTE_VARIABLE - rem_var *remv = new rem_var; - remv->ncolon = nc; - remv->index = ibuf; - remv->amv = group ? 1 : iamv; - remv->buffer = NULL; /*ACC*/ - - (el->lhs())->addAttribute(REMOTE_VARIABLE,(void *) remv, sizeof(rem_var)); - + SET_DVM(iaxis); } + if(group) { cur_st = cur_st->lexNext()->lexNext();//IF THEN after ELSE doAssignStmtAfter(WaitBG(GROUP_REF(group,1))); diff --git a/dvm/fdvm/trunk/fdvm/funcall.cpp b/dvm/fdvm/trunk/fdvm/funcall.cpp index 1c387d7..09b3d3a 100644 --- a/dvm/fdvm/trunk/fdvm/funcall.cpp +++ b/dvm/fdvm/trunk/fdvm/funcall.cpp @@ -3702,13 +3702,16 @@ SgStatement *Consistent_H (int il, SgExpression *hedr, SgExpression *axis_list) return(call); } -SgStatement *LoopRemoteAccess_H (int il, SgExpression *hedr, SgExpression *axis_list) -{// generating subroutine call: dvmh_loop_remote_access_(const DvmType *pCurLoop, const DvmType dvmDesc[], const DvmType *pRank, /* const DvmType *pAlignmentHelper */...) +SgStatement *LoopRemoteAccess_H (int il, SgExpression *hedr, SgSymbol *ar, SgExpression *axis_list) +{// generating subroutine call: dvmh_loop_remote_access_(const DvmType *pCurLoop, const DvmType dvmDesc[], const void *baseAddr, const DvmType *pRank, /* const DvmType *pAlignmentHelper */...) // DvmhLoopRef - result of dvmh_loop_create() SgCallStmt *call = new SgCallStmt(*fdvm[LOOP_REMOTE]); fmask[LOOP_REMOTE] = 2; call->addArg(*DVM000(il)); call->addArg(*hedr); + SgType *t = (isSgArrayType(ar->type())) ? ar->type()->baseType() : ar->type(); + SgExpression *base = (t->variant() != T_DERIVED_TYPE && t->variant() != T_STRING ) ? new SgArrayRefExp(*baseMemory(SgTypeInt())) : new SgArrayRefExp(*baseMemory(t)); + call->addArg(*base); AddListToList(call->expr(0), axis_list); return(call); } @@ -4411,6 +4414,16 @@ SgStatement *FillLocalPart_HH(SgSymbol *loop_s, SgSymbol *shead, SgSymbol *spart return(call); } +SgStatement *GetRemoteBuf (SgSymbol *loop_s, int n, SgSymbol *s_buf_head) +{// generating subroutine call: dvmh_loop_get_remote_buf_(const DvmType *pCurLoop, const DvmType *pRmaIndex, DvmType rmaDesc[]); + + SgCallStmt *call = new SgCallStmt(*fdvm[GET_REMOTE_BUF]); + fmask[GET_REMOTE_BUF] = 2; + call->addArg(*new SgVarRefExp(loop_s)); + call->addArg(*ConstRef_F95(n)); + call->addArg(*new SgArrayRefExp(*s_buf_head)); + return(call); +} //------ Calls from handlers for sequence of statements -------------------- @@ -4707,13 +4720,14 @@ SgExpression *GetDeviceNum(SgSymbol *s_loop_ref) { // generating function call: // DvmType loop_get_device_num_ (DvmhLoopRef *InDvmhLoop) // or when RTS2 is used - // DvmType dvmh_loop_get_device_num_(const DvmType *pCurLoop) + // DvmType dvmh_loop_get_device_num_C ( DvmType curLoop) - int fNum = INTERFACE_RTS2 ? GET_DEVICE_NUM_2 : GET_DEVICE_NUM ; + int fNum = INTERFACE_RTS2 ? GET_DEVICE_NUM_2 : GET_DEVICE_NUM ; SgFunctionCallExp *fe = new SgFunctionCallExp(*fdvm[fNum]); - - fe->addArg(* new SgVarRefExp(s_loop_ref)); - + if(INTERFACE_RTS2) + fe->addArg(SgDerefOp(*new SgVarRefExp(s_loop_ref))); + else + fe->addArg(* new SgVarRefExp(s_loop_ref)); return(fe); } @@ -4751,6 +4765,15 @@ SgExpression *FillBounds(SgSymbol *loop_s, SgSymbol *sBlow,SgSymbol *sBhigh,SgSy return(fe); } +SgExpression *LoopGetRemoteBuf(SgSymbol *loop_s, int n, SgSymbol *s_buf_head) +{// generating function call: dvmh_loop_get_remote_buf_(const DvmType *pCurLoop, const DvmType *pRmaIndex, DvmType rmaDesc[]); + SgFunctionCallExp *fe = new SgFunctionCallExp(*fdvm[GET_REMOTE_BUF_C]); + fe->addArg(SgDerefOp(*new SgVarRefExp(loop_s))); + fe->addArg(*new SgValueExp(n)); + fe->addArg(*new SgArrayRefExp(*s_buf_head)); + return(fe); +} + SgExpression *RedPost(SgSymbol *loop_s, SgSymbol *s_var_num, SgSymbol *sRed,SgSymbol *sLoc) {// generating function call: // void loop_red_post_(DvmhLoopRef *InDvmhLoop, DvmType *InRedNum, void *arrayPtr, void *locPtr) @@ -4761,7 +4784,7 @@ SgExpression *RedPost(SgSymbol *loop_s, SgSymbol *s_var_num, SgSymbol *sRed,SgSy int fNum = INTERFACE_RTS2 ? RED_POST_2 : RED_POST_C ; SgFunctionCallExp *fe = new SgFunctionCallExp(*fdvm[fNum]); - fe -> addArg(* new SgVarRefExp(loop_s)); + fe->addArg(* new SgVarRefExp(loop_s)); fe->addArg(SgAddrOp(* new SgVarRefExp(s_var_num))); fe->addArg(SgAddrOp(* new SgVarRefExp(sRed))); if(sLoc) @@ -4893,12 +4916,14 @@ SgExpression *GuessIndexType(SgSymbol *s_loop_ref) {// generating function call: // loop_guess_index_type_(DvmhLoopRef *InDvmhLoop) // or when RTS2 is used - // dvmh_loop_guess_index_type_(const DvmType *pCurLoop) + // dvmh_loop_guess_index_type_C(DvmType *curLoop) int fNum = INTERFACE_RTS2 ? GUESS_INDEX_TYPE_2 : GUESS_INDEX_TYPE ; - SgFunctionCallExp *fe = new SgFunctionCallExp(*fdvm[fNum]); - - fe -> addArg(* new SgVarRefExp(s_loop_ref)); + SgFunctionCallExp *fe = new SgFunctionCallExp(*fdvm[fNum]); + if(INTERFACE_RTS2) + fe->addArg(SgDerefOp(*new SgVarRefExp(s_loop_ref))); + else + fe->addArg(*new SgVarRefExp(s_loop_ref)); return(fe); } diff --git a/dvm/fdvm/trunk/fdvm/parloop.cpp b/dvm/fdvm/trunk/fdvm/parloop.cpp index 6dc5acc..fd70b5f 100644 --- a/dvm/fdvm/trunk/fdvm/parloop.cpp +++ b/dvm/fdvm/trunk/fdvm/parloop.cpp @@ -460,7 +460,11 @@ int WhatInterface(SgStatement *stmt) case ACC_TIE_OP: case CONSISTENT_OP: case STAGE_OP: - break; + case REMOTE_ACCESS_OP: + if(e->symbol()) // asynchronous REMOTE_ACCESS + return(1); + else + break; case REDUCTION_OP: if(TestReductionClause(e)) break; @@ -2213,6 +2217,21 @@ SgExpression *AxisList(SgStatement *stmt, SgExpression *tied_array_ref) return arglist; } +SgExpression *ArrayRefAddition(SgExpression *aref) +{ + if(!aref->lhs()) // without subscript list + { + // A => A(:,:,...,:) + SgExpression *arlist = NULL; + int n = Rank(aref->symbol()); + while(n--) + arlist = AddListToList(arlist, new SgExprListExp(*new SgExpression(DDOT))); + + aref->setLhs(arlist); + } + return aref; +} + SgExpression *MappingList(SgStatement *stmt, SgExpression *aref) { SgExpression *axis[MAX_LOOP_LEVEL], @@ -2280,6 +2299,16 @@ void Interface_2(SgStatement *stmt,SgExpression *clause[],SgExpression *init[],S for (SgExpression *el = clause[CONSISTENT_]->lhs(); el; el=el->rhs()) InsertNewStatementAfter(Consistent_H(ilh, HeaderForArrayInParallelDir(el->lhs()->symbol(), stmt, 0), MappingList(stmt, el->lhs())), cur_st, cur_st->controlParent()); + if (clause[REMOTE_ACCESS_]) //there is REMOTE_ACCESS clause + { int nbuf=1; + //adding new element to remote_access directive/clause list + AddRemoteAccess(clause[REMOTE_ACCESS_]->lhs(),NULL); + RemoteVariableList(clause[REMOTE_ACCESS_]->symbol(), clause[REMOTE_ACCESS_]->lhs(), stmt); + + for (SgExpression *el=clause[REMOTE_ACCESS_]->lhs(); el; el=el->rhs(),nbuf++) + InsertNewStatementAfter(LoopRemoteAccess_H(ilh, HeaderForArrayInParallelDir(el->lhs()->symbol(), stmt, 0), el->lhs()->symbol(), MappingList(stmt, ArrayRefAddition(el->lhs()))), cur_st, cur_st->controlParent()); + } + if (clause[SHADOW_COMPUTE_]) //there is SHADOW_COMPUTE clause { if ( (clause[SHADOW_COMPUTE_]->lhs())) diff --git a/dvm/fdvm/trunk/include/dvm.h b/dvm/fdvm/trunk/include/dvm.h index bd4baf8..785de47 100644 --- a/dvm/fdvm/trunk/include/dvm.h +++ b/dvm/fdvm/trunk/include/dvm.h @@ -260,6 +260,7 @@ const int DEFERRED_SHAPE = 1049; const int END_OF_USE_LIST = 1050; /*ACC*/ const int ROUTINE_ATTR = 1051; /*ACC*/ const int DATA_REGION_SYMB = 1052; /*ACC*/ +const int REMOTE_ACCESS_BUF = 1053; /*ACC*/ const int MAX_LOOP_LEVEL = 20; // 7 - maximal number of loops in parallel loop nest const int MAX_LOOP_NEST = 25; // maximal number of nested loops @@ -421,6 +422,7 @@ const int Logical_8 = 12; #define USE_STATEMENTS_ARE_REQUIRED ( (int *) first_do_par->attributeValue(0,MODULE_USE) ) #define DEFERRED_SHAPE_TEMPLATE(A) ( (ORIGINAL_SYMBOL(A))->attributeValue(0,DEFERRED_SHAPE) ) #define HAS_ROUTINE_ATTR(A) ((A)->attributeValue(0,ROUTINE_ATTR)) +#define IS_REMOTE_ACCESS_BUFFER(A) ((A)->attributeValue(0,REMOTE_ACCESS_BUF)) EXTERN SgFunctionSymb * fdvm [MAX_LIBFUN_NUM]; @@ -674,6 +676,7 @@ int CreateBufferArray(int rank, SgExpression *rme, int *amview, SgStatement *stm void CopyToBuffer(int rank, int ibuf, SgExpression *rme); void RemoteVariableList(SgSymbol *group,SgExpression *rml, SgStatement *stmt); void RemoteVariableList1(SgSymbol *group,SgExpression *rml, SgStatement *stmt); +SgExpression *AlignmentListForRemoteDir(int nt, SgExpression *axis[], SgExpression *coef[], SgExpression *cons[]); void DeleteBuffers(SgExpression *rml); void AddRemoteAccess(SgExpression *rml, SgStatement *rmout); void DelRemoteAccess(); @@ -1123,6 +1126,7 @@ void CudaBlockSize(SgExpression *cuda_block_list); void CudaBlockSize(SgExpression *cuda_block_list,SgExpression *esize[]); int ListElemNumber(SgExpression *list); SgStatement *Create_Host_Across_Loop_Subroutine(SgSymbol *sHostProc); +SgStatement *Create_Host_Loop_Subroutine_Main(SgSymbol *sHostProc); SgStatement *Create_Host_Loop_Subroutine(SgSymbol *sHostProc, int type); char * BoundName(SgSymbol *s, int i, int isLower); SgSymbol *DummyBoundSymbol(SgSymbol *rv, int i, int isLower, SgStatement *st_hedr); @@ -1207,7 +1211,8 @@ void RefIn_LoopHeaderExpr(SgExpression *e,SgStatement *dost); SgSymbol *RemoteAccessBufferInKernel(SgSymbol *ar,int rank); SgSymbol *isSameNameBuffer(char *name,SgExpression *rml); SgExpression *RemoteAccessHeaderList(); -void CreateRemoteAccessBuffers(); +void CreateRemoteAccessBuffersUp(); +void CreateRemoteAccessBuffers(SgExpression *rml, int pl_flag); coeffs *BufferCoeffs(SgSymbol *sbuf,SgSymbol *ar); void AddRemoteAccessBufferList_ToArrayList(); SgExpression * ExpressionListsUnion(SgExpression *list, SgExpression *alist); @@ -1378,6 +1383,7 @@ char *Header_DummyArgName(SgSymbol *s); SgExpression *Dimension(SgSymbol *hs, int i, int rank); SgSymbol *DummyDvmHeaderSymbol(SgSymbol *ar, SgStatement *st_hedr); SgSymbol *DummyDvmArraySymbol(SgSymbol *ar,SgSymbol *header_symb); +SgSymbol *DummyDvmBufferSymbol(SgSymbol *ar, SgSymbol *header_symb); SgExpression *ElementOfAddrArgumentList(SgSymbol *s); SgExpression *AddrArgumentList(); void CompareReductionAndPrivateList(); @@ -1821,6 +1827,7 @@ SgStatement *Realign_H(SgExpression *objref, int new_sign); SgExpression *GetOverallStep(SgSymbol *s_loop_ref); SgExpression *GetDeviceNum(SgSymbol *s_loop_ref); SgExpression *FillBounds(SgSymbol *loop_s, SgSymbol *sBlow,SgSymbol *sBhigh,SgSymbol *sBstep); +SgExpression *LoopGetRemoteBuf(SgSymbol *loop_s, int n, SgSymbol *s_buf_head); SgExpression *mallocFunction(SgExpression *arg, SgStatement *scope); SgExpression *freeFunction(SgExpression *arg, SgStatement *scope); SgExpression *RedPost(SgSymbol *loop_s, SgSymbol *s_var_num, SgSymbol *sRed,SgSymbol *sLoc); @@ -1888,8 +1895,10 @@ SgStatement *DvmhArrayCopyWhole( SgExpression *array_header_right, SgExpression SgStatement *Correspondence_H (int il, SgExpression *hedr, SgExpression *axis_list); SgStatement *DvmhArraySetValue( SgExpression *array_header_left, SgExpression *e_right ); SgStatement *Consistent_H (int il, SgExpression *hedr, SgExpression *axis_list); -SgStatement *LoopRemoteAccess_H (int il, SgExpression *hedr, SgExpression *axis_list); +SgStatement *LoopRemoteAccess_H (int il, SgExpression *hedr, SgSymbol *ar, SgExpression *axis_list); SgStatement *RemoteAccess_H2 (SgExpression *buf_hedr, SgSymbol *ar, SgExpression *ar_hedr, SgExpression *axis_list); +SgStatement *GetRemoteBuf (SgSymbol *loop_s, int n, SgSymbol *s_buf_head); + /* io.cpp */ void IO_ThroughBuffer(SgSymbol *ar, SgStatement *stmt, SgExpression *eiostat); int IOcontrol(SgExpression *e, SgExpression *ioc[],int type); diff --git a/dvm/fdvm/trunk/include/libdvm.h b/dvm/fdvm/trunk/include/libdvm.h index 6d7e3a7..cf521f5 100644 --- a/dvm/fdvm/trunk/include/libdvm.h +++ b/dvm/fdvm/trunk/include/libdvm.h @@ -264,6 +264,7 @@ name_dvm[SET_VALUE] = "dvmh_array_set_value"; name_dvm[LOOP_CONSISTENT] = "dvmh_loop_consistent"; name_dvm[DVMH_REMOTE2] = "dvmh_remote_access2"; name_dvm[LOOP_REMOTE] = "dvmh_loop_remote_access"; +name_dvm[GET_REMOTE_BUF] = "dvmh_loop_get_remote_buf"; name_dvm[FTN_OPEN] = "dvmh_ftn_open"; /* IO */ name_dvm[FTN_CLOSE] = "dvmh_ftn_close"; /* IO */ name_dvm[FTN_READ] = "dvmh_ftn_read_unf"; /* IO */ @@ -312,7 +313,7 @@ name_dvm[GET_DEVICE_ADDR_C]= "dvmh_get_device_addr_C"; name_dvm[GET_LOCAL_PART] = "loop_cuda_get_local_part"; name_dvm[GET_LOCAL_PART_C] = "dvmh_loop_cuda_get_local_part_C"; name_dvm[GET_DEVICE_NUM] = "loop_get_device_num_"; -name_dvm[GET_DEVICE_NUM_2] = "dvmh_loop_get_device_num_"; +name_dvm[GET_DEVICE_NUM_2] = "dvmh_loop_get_device_num_C"; name_dvm[GET_OVERALL_STEP] = "loop_cuda_get_red_step"; name_dvm[FILL_BOUNDS_C] = "loop_fill_bounds_"; name_dvm[FILL_BOUNDS_2] = "dvmh_loop_fill_bounds_"; @@ -330,5 +331,6 @@ name_dvm[GET_CONFIG] = "loop_cuda_get_config"; name_dvm[GET_CONFIG_C] = "dvmh_loop_cuda_get_config_C"; name_dvm[CHANGE_BOUNDS] = "dvmh_change_filled_bounds"; name_dvm[GUESS_INDEX_TYPE] = "loop_guess_index_type_"; -name_dvm[GUESS_INDEX_TYPE_2]= "dvmh_loop_guess_index_type_"; +name_dvm[GUESS_INDEX_TYPE_2]="dvmh_loop_guess_index_type_C"; name_dvm[RTC_SET_LANG] = "loop_cuda_rtc_set_lang"; +name_dvm[GET_REMOTE_BUF_C] = "dvmh_loop_get_remote_buf_C"; diff --git a/dvm/fdvm/trunk/include/libnum.h b/dvm/fdvm/trunk/include/libnum.h index 01a1f06..179ff55 100644 --- a/dvm/fdvm/trunk/include/libnum.h +++ b/dvm/fdvm/trunk/include/libnum.h @@ -265,6 +265,7 @@ enum { LOOP_CONSISTENT, DVMH_REMOTE2, LOOP_REMOTE, + GET_REMOTE_BUF, FTN_OPEN, FTN_CLOSE, FTN_READ, @@ -330,5 +331,6 @@ enum { GUESS_INDEX_TYPE, GUESS_INDEX_TYPE_2, RTC_SET_LANG, + GET_REMOTE_BUF_C, MAX_LIBFUN_NUM }; diff --git a/sapfor/experts/Sapfor_2017/CMakeLists.txt b/sapfor/experts/Sapfor_2017/CMakeLists.txt index be43305..d30abc3 100644 --- a/sapfor/experts/Sapfor_2017/CMakeLists.txt +++ b/sapfor/experts/Sapfor_2017/CMakeLists.txt @@ -331,6 +331,14 @@ set(MAIN _src/Sapfor.cpp set(PREDICTOR _src/Predictor/PredictScheme.cpp _src/Predictor/PredictScheme.h) +set(PROJ_MAN _src/ProjectManipulation/ParseFiles.cpp + _src/ProjectManipulation/ParseFiles.h + _src/ProjectManipulation/StdCapture.h + _src/ProjectManipulation/PerfAnalyzer.cpp + _src/ProjectManipulation/PerfAnalyzer.h + _src/ProjectManipulation/FileInfo.cpp + _src/ProjectManipulation/FileInfo.h) + set(PARSER ${parser_sources}/cftn.c ${parser_sources}/errors.c ${parser_sources}/gram1.tab.c @@ -413,7 +421,8 @@ set(SOURCE_EXE ${PPPA} ${ZLIB} ${GR_LAYOUT} - ${PR_PARAM}) + ${PR_PARAM} + ${PROJ_MAN}) add_executable(Sapfor_F ${SOURCE_EXE}) source_group (CFGraph FILES ${CFG}) @@ -454,6 +463,7 @@ source_group (SageExtension FILES ${OMEGA}) source_group (Utils FILES ${UTILS}) source_group (VerificationCode FILES ${VERIF}) source_group (ProjectParameters FILES ${PR_PARAM}) +source_group (ProjectManipulation FILES ${PROJ_MAN}) source_group (VisualizerCalls FILES ${VS_CALLS}) source_group (VisualizerCalls\\GraphLayout FILES ${GR_LAYOUT}) diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.cpp b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.cpp new file mode 100644 index 0000000..5e10ef0 --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.cpp @@ -0,0 +1,62 @@ +#include "../Utils/leak_detector.h" + +#include +#include + +#include +#include + +#include "FileInfo.h" +#include "../Utils/utils.h" + +using namespace std; + +string FileInfo::convertStyle(bool needRewrite) +{ + string tmp_text = text; + + vector splited; + splitString(tmp_text, '\n', splited); + + tmp_text = ""; + int z = 0; + for (auto& line : splited) + { + if (line[0] == 'c' || line[0] == 'C' || line[0] == 'd' || line[0] == 'D' || line[0] == '*') + line[0] = '!'; + + bool needContinuation = false; + if (line[0] != '!' && line.size() > 6) + { + if (line[5] != ' ' && !(line[5] > '0' && line[5] < '9')) // not label + { + line[5] = ' '; + needContinuation = true;// line[5] = '&'; + } + + int p = 73; + if (style == 1) + p = 133; + if (line.size() > p) + { + while (line[p] != '\0' && line[p] != '\n' && line[p] != '!') + { + line[p] = ' '; + p++; + if (p >= line.size()) + break; + } + } + } + + if (needContinuation) + tmp_text += "&"; + tmp_text += (z != 0 ? "\n" : "") + line; + ++z; + } + + if (needRewrite) + writeFileFromStr(fileName, tmp_text); + + return tmp_text; +} \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.h b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.h new file mode 100644 index 0000000..4bcb728 --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/FileInfo.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +struct FileInfo +{ + FileInfo() + { + fileName = ""; + options = ""; + errPath = ""; + outPath = ""; + outDepPath = ""; + text = ""; + error = -1; + includesAdded = 0; + style = -1; + lvl = 0; + } + + FileInfo(const std::string& _fileName, const std::string& _options, const std::string& _errPath, const std::string& _outPath, + const std::string& _outDepPath, const std::string& _text, int errorInit = -1) + { + fileName = _fileName; + options = _options; + errPath = _errPath; + outPath = _outPath; + outDepPath = _outDepPath; + text = _text; + error = errorInit; + includesAdded = 0; + style = -1; + lvl = 0; + } + + int error; + std::string fileName; + std::string options; + std::string errPath; + std::string outPath; + std::string outDepPath; + std::string text; + int style; // -1 unk, 0 fixed, 1 fixed ext, 2 free + int includesAdded; + std::set includes; + int lvl; + + std::string convertStyle(bool needRewrite = true); +}; diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/ParseFiles.cpp b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/ParseFiles.cpp new file mode 100644 index 0000000..27c92ac --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/ParseFiles.cpp @@ -0,0 +1,789 @@ +#include "../Utils/leak_detector.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../Utils/errors.h" +#include "../Utils/SgUtils.h" +#include "../VisualizerCalls/get_information.h" +#include "../VisualizerCalls/SendMessage.h" + +#include "ParseFiles.h" +#include "StdCapture.h" +#include "FileInfo.h" + +using namespace std; + +extern "C" int parse_file(int argc, char* argv[], char* proj_name); + +static void findModuleDeclInProject(const string& name, const vector& files, map& modDecls) +{ + char** filesList = new char* [files.size()]; + for (int z = 0; z < files.size(); ++z) + filesList[z] = (char*)files[z].c_str(); + + SgProject* tmpProj = new SgProject(name.c_str(), filesList, files.size()); + + int numF = tmpProj->numberOfFiles(); + set filesSg; + for (int z = 0; z < numF; ++z) + { + vector modules; + SgFile* currF = &tmpProj->file(z); + string fileName = currF->filename(); + convertToLower(fileName); + + filesSg.insert(currF); + + findModulesInFile(currF, modules); + for (auto& elem : modules) + { + if (string(elem->fileName()) == currF->filename()) + { + const string name = elem->symbol()->identifier(); + auto it = modDecls.find(name); + if (it != modDecls.end() && it->second != currF->filename()) + { + __spf_print(1, "found several module declaration of '%s' in files '%s' and '%s'\n", name.c_str(), it->second.c_str(), currF->filename()); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + else + modDecls.insert(it, make_pair(name, currF->filename())); + } + } + } + + delete []filesList; + InitializeTable(); +} + +static void createIncludeOrder(vector &toIncl, + const map& moduleDelc, + const map>& modDirectOrder, + set &done, + const string &curr) +{ + if (done.find(curr) == done.end()) + { + for (auto& elem : modDirectOrder.find(curr)->second) + createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, elem); + + if (done.find(curr) == done.end()) + { + toIncl.push_back(moduleDelc.find(curr)->second); + done.insert(curr); + } + } +} + +static set applyModuleDeclsForFile(FileInfo *forFile, const map &mapFiles, + const map& moduleDelc, + const map>& mapModuleDeps, + const map>& modDirectOrder, + vector &optSplited, + bool includeForInline = false) +{ + set retFilesMod; + + auto itF = mapModuleDeps.find(forFile->fileName); + if (itF == mapModuleDeps.end() && !includeForInline) + return retFilesMod; + + vector toIncl; + set done; + if (itF != mapModuleDeps.end()) + { + for (auto& mod : itF->second) + if (moduleDelc.find(mod) != moduleDelc.end()) + createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, mod); + } + + //rewrite files to the next iter of parse + set allFiles; + bool needToConvertStyle = false; + for (auto& incl : toIncl) + { + if (mapFiles.find(incl) == mapFiles.end()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + allFiles.insert(mapFiles.find(incl)->second); + } + allFiles.insert(forFile); + + int style = forFile->style; + for (auto& elem : allFiles) + { + if (style != elem->style) + { + needToConvertStyle = true; + break; + } + } + + string mainText = forFile->text; + if (needToConvertStyle) + { + for (auto& elem : allFiles) + { + if (elem->style != 2) + { + retFilesMod.insert(elem); + if (elem != forFile) + elem->convertStyle(); + else + mainText = elem->convertStyle(false); + } + } + + if (forFile->style != 2) + { + for (auto& opt : optSplited) + { + if (opt == "-FI" || opt == "-extend_source") + opt = "-FR"; + } + } + } + + string include = ""; + int includeCount = 0; + set included; + for (auto& incl : toIncl) + { + if (included.find(incl) == included.end()) + { + include += " include '" + incl + "'\n"; + includeCount++; + } + included.insert(incl); + } + + vector toInclEnds; + string includeLast = ""; + + if (includeForInline) + { + //find needed modules first + vector filesWithModules; + for (auto& elem : moduleDelc) + filesWithModules.push_back(elem.second); + for (auto& file : filesWithModules) + { + if (file != forFile->fileName && included.find(file) == included.end()) + { + toInclEnds.push_back(file); + included.insert(file); + } + } + + for (auto& file : mapFiles) + if (file.second != forFile && included.find(file.second->fileName) == included.end()) + toInclEnds.push_back(file.second->fileName); + + if (toInclEnds.size()) + includeLast += "!SPF SHADOW FILES\n"; + + for (auto& incl : toInclEnds) + includeLast += " include '" + incl + "'\n"; + } + + if (includeCount) + include = "!SPF NUM FILES " + std::to_string(includeCount) + "\n" + include; + + const string data = include + mainText + includeLast; + __spf_print(1, "include to file %s before\n", forFile->fileName.c_str()); + __spf_print(1, "%s", include.c_str()); + __spf_print(1, "include to file %s after\n", forFile->fileName.c_str()); + __spf_print(1, "%s", includeLast.c_str()); + + writeFileFromStr(forFile->fileName, data); + + forFile->includesAdded = included.size(); + forFile->includes = included; + + retFilesMod.insert(forFile); + return retFilesMod; +} + +static void restoreOriginalText(const vector& listOfProject) +{ + for (auto& elem : listOfProject) + writeFileFromStr(elem.fileName, elem.text); + fflush(NULL); +} + +static inline void restoreOriginalText(const FileInfo& file) +{ + writeFileFromStr(file.fileName, file.text); +} + +static void checkRetCode(FileInfo& info, const string& errorMessage) +{ + if (info.error != 0) + info.lvl++; + + if (errorMessage.find("Warning 308") != string::npos) + if (info.error == 0) + info.error = 1; +} + +static vector parseList(vector& listOfProject, + bool needToInclude, bool needToIncludeForInline, + const map> &mapModuleDeps, + const map &moduleDelc, + const map> &modDirectOrder, bool isFromConsole = false) +{ + map mapFiles; + for (auto& elem : listOfProject) + mapFiles[elem.fileName] = &elem; + + vector errors; + int i = 1; + int N = listOfProject.size(); + for (auto& elem : listOfProject) + { + sendMessage_progress(std::to_wstring((int)(((double)(i++) / N) * 100))); + + string file = elem.fileName; + string options = elem.options; + vector optSplited = splitAndArgvCreate(options); + + char** toParse = new char* [optSplited.size() + 1]; + for (int z = 0; z < optSplited.size(); ++z) + { + toParse[z] = new char[optSplited[z].size() + 1]; + strcpy(toParse[z], optSplited[z].c_str()); + } + toParse[optSplited.size()] = new char[file.size() + 1]; + strcpy(toParse[optSplited.size()], file.c_str()); + + if (options.find("-FI") != string::npos) + elem.style = 0; + else if (options.find("-FR") != string::npos || options.find("-f90") != string::npos) + elem.style = 2; + else if (options.find("-extend_source") != string::npos) + elem.style = 1; + + for (int z = 0; z < optSplited.size(); ++z) + { + if (optSplited[z] == "-o") + { + if (z + 1 == optSplited.size()) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + elem.outDepPath = optSplited[z + 1]; + break; + } + } + + FILE* depPath = fopen(elem.outDepPath.c_str(), "r"); + if (depPath && !isFromConsole) + { + fclose(depPath); + if (elem.error <= 0) + { + elem.error = 0; + errors.push_back(""); + for (int z = 0; z <= optSplited.size(); ++z) + delete toParse[z]; + delete[] toParse; + continue; + } + } + +#ifdef _WIN32 + sendMessage_2lvl(L" обработка файла '" + to_wstring(file) + L"'"); +#else + sendMessage_2lvl(L" processing file '" + to_wstring(file) + L"'"); +#endif + StdCapture stdCapture; + stdCapture.Init(); + string errorMessage = ""; + try + { + set filesModified; + stdCapture.BeginCapture(); + if (needToInclude) + filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline); + else if (needToIncludeForInline) // TODO for modules + filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline); + + int retCode = parse_file(optSplited.size(), toParse, "dvm.proj"); + if (needToInclude || needToIncludeForInline) + { + for (auto &elem : filesModified) + restoreOriginalText(*elem); + fflush(NULL); + } + + elem.error = retCode; + stdCapture.EndCapture(); + errorMessage = stdCapture.GetCapture(); + checkRetCode(elem, errorMessage); + } + catch (int err) + { + stdCapture.EndCapture(); + errorMessage = stdCapture.GetCapture(); + + if (needToInclude || needToIncludeForInline) + restoreOriginalText(listOfProject); + } + catch (...) + { + stdCapture.EndCapture(); + errorMessage = stdCapture.GetCapture(); + + if (needToInclude || needToIncludeForInline) + restoreOriginalText(listOfProject); + } + errors.push_back(errorMessage); + for (int z = 0; z <= optSplited.size(); ++z) + delete toParse[z]; + delete[] toParse; + + createNeededException(); + } + return errors; +} + +static string shiftLines(const string &in, const map &mapOfFiles, const FileInfo* currF) +{ + int byNum = 0; + + auto it = in.find("on line "); + if (it != string::npos) + it += strlen("on line "); + + int d = 0; + sscanf(in.c_str() + it, "%d", &d); + + auto it1 = in.find("of", it + 1); + if (it1 == string::npos) + return in; + it1 += 3; + + string fileN = in.substr(it1, in.find(':', it1) - it1); + auto itF = mapOfFiles.find(fileN); + if (itF == mapOfFiles.end()) + return in; + if (itF->second != currF) + return in; + + byNum = itF->second->includesAdded; + if (byNum == 0) + return in; + + if (d - byNum <= 0) + { + //return in; + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + else + d -= byNum; + + string newStr = in.substr(0, it) + std::to_string(d) + in.substr(in.find(' ', it + 1)); + return newStr; +} + +static int dumpErrors(const vector& listOfProject, const vector& errors) +{ + int errorsCount = 0; + map mapOfFiles; + for (auto& elem : listOfProject) + mapOfFiles[elem.fileName] = &elem; + + int z = 0; + for (auto& file : listOfProject) + { + if (errors[z] == "") + { + FILE* ferr = fopen(file.errPath.c_str(), "w"); + if (!ferr) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + fclose(ferr); + ++z; + continue; + } + + FILE* ferr = fopen(file.errPath.c_str(), "w"); + FILE* fout = fopen(file.outPath.c_str(), "w"); + if (!ferr) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + if (!fout) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + string errS = "", outS = ""; + vector splited; + splitString(errors[z], '\n', splited); + for (auto& elem : splited) + { + if (elem.find("Warning 308") != string::npos) + outS += shiftLines(elem, mapOfFiles, &file) + "\n"; + else if (elem.find("Error") != string::npos) + { + errS += shiftLines(elem, mapOfFiles, &file) + "\n"; + errorsCount++; + } + } + + fprintf(fout, "%s", outS.c_str()); + fprintf(ferr, "%s", errS.c_str()); + + fflush(NULL); + + fclose(fout); + fclose(ferr); + ++z; + } + + return errorsCount; +} + +static int createMapOfUse(const vector& errors, const vector& listOfProject, map> &mapModuleDeps) +{ + int changed = 0; + for (int z = 0; z < listOfProject.size(); ++z) + { + if (listOfProject[z].error >= 0) + { + vector splited; + splitString(errors[z], '\n', splited); + for (auto& err : splited) + { + if (err.find("Warning 308") != string::npos && err.find(listOfProject[z].fileName) != string::npos) + { + auto pos = err.find("Unknown module"); + if (pos != string::npos) + { + pos += strlen("Unknown module") + 1; + string substr = ""; + while (err[pos] != ' ' && pos != err.size()) + substr += err[pos++]; + mapModuleDeps[listOfProject[z].fileName].insert(substr); + changed++; + } + } + } + } + } + + return changed; +} + +static map> createModuleOrder(const map &moduleDelc, const map> &mapModuleDeps) +{ + map> modDirectOrder; + for (auto& elem : moduleDelc) + modDirectOrder[elem.first] = set(); + + for (auto& elem : moduleDelc) + { + auto itF = mapModuleDeps.find(elem.second); + if (itF != mapModuleDeps.end()) + { + for (auto& inFile : itF->second) + { + if (moduleDelc.find(inFile) != moduleDelc.end()) + modDirectOrder[elem.first].insert(inFile); + } + } + } + + return modDirectOrder; +} + +static void printDebug(const map>& mapModuleDeps, const map>& modDirectOrder, + const vector& listOfProject, bool console = false) +{ + string toPrint = "MODULE DEPS:\n"; + for (auto& elem : mapModuleDeps) + { + toPrint += elem.first + '\n'; + for (auto& setEl : elem.second) + toPrint += " " + setEl + '\n'; + } + toPrint += "MODULE DIRECT ORDER:\n"; + for (auto& elem : modDirectOrder) + { + toPrint += elem.first + '\n'; + for (auto& setEl : elem.second) + toPrint += " " + setEl + '\n'; + } + toPrint += "FILES LVL:\n"; + for (auto& elem : listOfProject) + toPrint += elem.fileName + " " + elem.outDepPath + " lvl = " + std::to_string(elem.lvl) + '\n'; + if (console) + printf("%s\n", toPrint.c_str()); + __spf_print(1, "%s\n", toPrint.c_str()); +} + +static int parseFiles(vector& errors, vector& listOfProject, vector& filesCompilationOrder, + int parseForInlining, bool isFromConsole = false) +{ + int rethrow = 0; + int iters = 0; + int changed = 0; + int lastChanged = 0; + const string projName = "tmp"; + + map> mapModuleDeps; + map moduleDelc; + map> modDirectOrder; + + try + { + do + { +#ifdef _WIN32 + sendMessage_1lvl(L"выполняется " + std::to_wstring((iters + 1)) + L" итерация синтаксического анализа"); +#else + sendMessage_1lvl(L"running " + std::to_wstring((iters + 1)) + L" iteration of syntax analisys"); +#endif + errors = parseList(listOfProject, iters != 0, (parseForInlining != 0), mapModuleDeps, moduleDelc, modDirectOrder, isFromConsole); + changed = createMapOfUse(errors, listOfProject, mapModuleDeps); + if (iters != 0) + if (lastChanged <= changed) + break; + + createNeededException(); + + if (changed) + { + vector files; + for (auto& elem : listOfProject) + if (elem.error == 0) + files.push_back(elem.outDepPath); + if (files.size() == 0) + break; + findModuleDeclInProject(projName + std::to_string(iters++), files, moduleDelc); + modDirectOrder = createModuleOrder(moduleDelc, mapModuleDeps); + } + lastChanged = changed; + //printDebug(mapModuleDeps, modDirectOrder, listOfProject); + } while (changed); + + + //printDebug(mapModuleDeps, modDirectOrder, listOfProject); + + int added = 0; + int iter = 0; + vector files; + while (added != listOfProject.size()) + { + for (auto& elem : listOfProject) + { + if (elem.lvl == iter) + { + files.push_back(elem.fileName); + added++; + } + } + ++iter; + } + + map> fileDeps; + for (auto& file : files) + { + fileDeps[file] = set(); + if (mapModuleDeps.find(file) == mapModuleDeps.end()) + continue; + + for (auto& dep : mapModuleDeps[file]) + { + if (moduleDelc.find(dep) == moduleDelc.end()) + continue; + fileDeps[file].insert(moduleDelc[dep]); + } + } + + set addedFiles; + + added = 0; + while (added != fileDeps.size()) + { + for (auto& file : fileDeps) + { + bool depsAdded = true; + for (auto& dep : file.second) + if (addedFiles.find(dep) == addedFiles.end()) + depsAdded = false; + + if (depsAdded && addedFiles.find(file.first) == addedFiles.end()) + { + filesCompilationOrder.push_back(file.first); + addedFiles.insert(file.first); + added++; + } + } + } + + + __spf_print(1, "files compilation order:\n"); + for (auto& file : filesCompilationOrder) + __spf_print(1, " %s\n", file.c_str()); + } + catch (int err) + { + rethrow = err; + } + catch (...) + { + rethrow = -1; + } + return rethrow; +} + +int parseFiles(const char* proj, vector& filesCompilationOrder, int parseForInlining) +{ + FILE* list = fopen(proj, "r"); + if (!list) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + vector pathSplit; + if (string(proj).find('\\') != string::npos) + splitString(proj, '\\', pathSplit); + else + splitString(proj, '/', pathSplit); + + if (pathSplit.size() < 2) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + if (pathSplit[pathSplit.size() - 2] != "visualiser_data") + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + string fullPath = ""; + for (int z = 0; z < pathSplit.size() - 2; ++z) + fullPath += pathSplit[z] + "/"; + if (fullPath == "") + fullPath = "./"; + else + { + //change dir + if (chdir(fullPath.c_str()) != 0) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + + vector listOfProject; + while (!feof(list)) + { + char buf[1024]; + if (fgets(buf, 1024, list) == NULL) + continue; + + string toAdd = buf; + if (toAdd[toAdd.size() - 1] == '\n') + toAdd = toAdd.erase(toAdd.size() - 1); + + string fileNameFixed = ""; + auto idx = toAdd.find(fullPath); + if (idx != string::npos) + fileNameFixed = toAdd.substr(idx + fullPath.size()); + else + fileNameFixed = (toAdd.substr(0, 2) == "./") ? toAdd.substr(2) : toAdd; + + const string optPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".opt"; + const string errPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".err"; + const string outPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".out"; + + const string fileText = readFileToStr(toAdd); + + FILE* opt = fopen(optPath.c_str(), "r"); + if (!opt) + { + __spf_print(1, "can not open path %s\n", optPath.c_str()); + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + } + fgets(buf, 1024, opt); + string toAddOpt = buf; + if (toAddOpt[toAddOpt.size() - 1] == '\n') + toAddOpt = toAddOpt.erase(toAddOpt.size() - 1); + + fclose(opt); + listOfProject.push_back(FileInfo(fileNameFixed, toAddOpt, errPath, outPath, "", fileText)); + } + + fclose(list); + vector errors; + + int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, parseForInlining); + int errCount = dumpErrors(listOfProject, errors); + + if (rethrow != 0) + throw rethrow; + return -errCount; +} + +void parseFiles(int argc, char** argv) +{ + bool isInline = false; + auto result = splitCommandLineForParse(argv, argc, isInline); + if (result.second.size() == 0) + { + printf("Nothing to parse\n"); + exit(0); + } + + int code = 0; + + vector errors; + vector listOfProject; + + string toAddOpt = ""; + for (auto& opt : result.first) + toAddOpt += opt + " "; + + for (auto& file : result.second) + { + const string fileText = readFileToStr(file); + listOfProject.push_back(FileInfo(file, toAddOpt + "-o " + file + ".dep", "", "", "", fileText, 0)); + } + + vector filesCompilationOrder; + int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true); + if (rethrow == 0) + { + for (auto& err : errors) + { + vector splited; + splitString(err, '\n', splited); + for (auto& elem : splited) + { + if (elem.find("Error") != string::npos) + { + printf("%s\n", elem.c_str()); + code++; + } + } + } + } + + if (code == 0 && rethrow == 0) + { + FILE* proj = fopen("dvm.proj", "w"); + if (proj == NULL) + printInternalError(convertFileName(__FILE__).c_str(), __LINE__); + + for (auto& file : result.second) + fprintf(proj, "%s.dep\n", file.c_str()); + printf("Parsing was completed successfully\n"); + } + else + printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code); + exit(0); +} diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/ParseFiles.h b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/ParseFiles.h new file mode 100644 index 0000000..c9f908b --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/ParseFiles.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include + +int parseFiles(const char* proj, std::vector& filesCompilationOrder, int parseForInlining); +void parseFiles(int argc, char** argv); diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/PerfAnalyzer.cpp b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/PerfAnalyzer.cpp new file mode 100644 index 0000000..e16206f --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/PerfAnalyzer.cpp @@ -0,0 +1,38 @@ +#include "../Utils/leak_detector.h" + +#include +#include + +#include +#include + +#include "../Utils/errors.h" +#include "../Utils/SgUtils.h" +#include "../VisualizerCalls/get_information.h" +#include "../VisualizerCalls/SendMessage.h" + +#include "StdCapture.h" + +using namespace std; + +extern int pppa_analyzer(int argv, char** argc); + +int pppaAnalyzer(const char* options) +{ + string optionsS(options); + vector splited = splitAndArgvCreate(optionsS); + + char** argv = new char* [splited.size()]; + for (int z = 0; z < splited.size(); ++z) + argv[z] = (char*)splited[z].c_str(); + + StdCapture stdCapture; + stdCapture.Init(); + string errorMessage = ""; + int retCode = pppa_analyzer(splited.size(), argv); + stdCapture.EndCapture(); + errorMessage = stdCapture.GetCapture(); + + delete []argv; + return retCode; +} diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/PerfAnalyzer.h b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/PerfAnalyzer.h new file mode 100644 index 0000000..5e81a81 --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/PerfAnalyzer.h @@ -0,0 +1,3 @@ +#pragma once + +int pppaAnalyzer(const char* options); \ No newline at end of file diff --git a/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/StdCapture.h b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/StdCapture.h new file mode 100644 index 0000000..b0ab35b --- /dev/null +++ b/sapfor/experts/Sapfor_2017/_src/ProjectManipulation/StdCapture.h @@ -0,0 +1,190 @@ +#pragma once + +#include +#include +#include + +#ifdef _WIN32 +#include +#include + +#define popen _popen +#define pclose _pclose +#define stat _stat +#define dup _dup +#define dup2 _dup2 +#define fileno _fileno +#define close _close +#define pipe _pipe +#define read _read +#define eof _eof +#else +#include +#endif + +#ifndef STD_OUT_FD +#define STD_OUT_FD (fileno(stdout)) +#endif + +#ifndef STD_ERR_FD +#define STD_ERR_FD (fileno(stderr)) +#endif + +class StdCapture +{ + int m_pipe[2]; + int m_oldStdOut; + int m_oldStdErr; + bool m_capturing; + std::mutex m_mutex; + std::string m_captured; + + enum PIPES { READ, WRITE }; + + int secure_dup(int src) + { + int ret = -1; + bool fd_blocked = false; + do + { + ret = dup(src); + fd_blocked = (errno == EINTR || errno == EBUSY); + if (fd_blocked) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } while (ret < 0); + return ret; + } + + void secure_pipe(int* pipes) + { + int ret = -1; + bool fd_blocked = false; + do + { +#ifdef _WIN32 + ret = pipe(pipes, 1024 * 1024 * 20, O_BINARY); // 20 MB +#else + ret = pipe(pipes) == -1; + fcntl(*pipes, F_SETPIPE_SZ, 1024 * 1024 * 20); +#endif + fd_blocked = (errno == EINTR || errno == EBUSY); + if (fd_blocked) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } while (ret < 0); + } + + void secure_dup2(int src, int dest) + { + int ret = -1; + bool fd_blocked = false; + do + { + ret = dup2(src, dest); + fd_blocked = (errno == EINTR || errno == EBUSY); + if (fd_blocked) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } while (ret < 0); + } + + void secure_close(int& fd) + { + int ret = -1; + bool fd_blocked = false; + do + { + ret = close(fd); + fd_blocked = (errno == EINTR); + if (fd_blocked) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } while (ret < 0); + + fd = -1; + } + +public: + void Init() + { + // make stdout & stderr streams unbuffered + // so that we don't need to flush the streams + // before capture and after capture + // (fflush can cause a deadlock if the stream is currently being + std::lock_guard lock(m_mutex); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + } + + void BeginCapture() + { + std::lock_guard lock(m_mutex); + if (m_capturing) + return; + + secure_pipe(m_pipe); + m_oldStdOut = secure_dup(STD_OUT_FD); + m_oldStdErr = secure_dup(STD_ERR_FD); + secure_dup2(m_pipe[WRITE], STD_OUT_FD); + secure_dup2(m_pipe[WRITE], STD_ERR_FD); + m_capturing = true; +#ifndef _WIN32 + secure_close(m_pipe[WRITE]); +#endif + } + + bool IsCapturing() + { + std::lock_guard lock(m_mutex); + return m_capturing; + } + + void EndCapture() + { + std::lock_guard lock(m_mutex); + if (!m_capturing) + return; + + m_captured.clear(); + secure_dup2(m_oldStdOut, STD_OUT_FD); + secure_dup2(m_oldStdErr, STD_ERR_FD); + + const int bufSize = 1025; + char buf[bufSize]; + int bytesRead = 0; + bool fd_blocked(false); + do + { + bytesRead = 0; + fd_blocked = false; +#ifdef _WIN32 + if (!eof(m_pipe[READ])) + bytesRead = read(m_pipe[READ], buf, bufSize - 1); +#else + bytesRead = read(m_pipe[READ], buf, bufSize - 1); +#endif + if (bytesRead > 0) + { + buf[bytesRead] = 0; + m_captured += buf; + } + else if (bytesRead < 0) + { + fd_blocked = (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR); + if (fd_blocked) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } while (fd_blocked || bytesRead == (bufSize - 1)); + + secure_close(m_oldStdOut); + secure_close(m_oldStdErr); + secure_close(m_pipe[READ]); +#ifdef _WIN32 + secure_close(m_pipe[WRITE]); +#endif + m_capturing = false; + } + + std::string GetCapture() + { + std::lock_guard lock(m_mutex); + return m_captured; + } +}; diff --git a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp index 3edd5a6..ccd563d 100644 --- a/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Sapfor.cpp @@ -33,6 +33,8 @@ #include "Utils/errors.h" #include "Utils/SgUtils.h" +#include "ProjectManipulation/ParseFiles.h" + #include "LoopAnalyzer/loop_analyzer.h" #include "LoopAnalyzer/loop_analyzer_nodist.h" @@ -2564,11 +2566,8 @@ void runPass(const int curr_regime, const char *proj_name, const char *folderNam } } -extern "C" int parse_file(int argc, char* argv[], char* proj_name); extern int pppa_analyzer(int argv, char** argc); -bool runAsClient = false; - int main(int argc, char **argv) { int leakMemDump = 0; @@ -2730,62 +2729,7 @@ int main(int argc, char **argv) else if (string(curr_arg) == "-autoArray") parallizeFreeLoops = 1; else if (string(curr_arg) == "-parse") - { - bool isInline = false; - auto result = splitCommandLineForParse(argv + (i + 1), argc - (i + 1), isInline); - if (result.second.size() == 0) - { - printf("Nothing to parse\n"); - exit(0); - } - - int code = 0; - - vector errors; - vector listOfProject; - - string toAddOpt = ""; - for (auto& opt : result.first) - toAddOpt += opt + " "; - - for (auto& file : result.second) - { - const string fileText = readFileToStr(file); - listOfProject.push_back(FileInfo(file, toAddOpt + "-o " + file + ".dep", "", "", "", fileText, 0)); - } - - int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, isInline, true); - if (rethrow == 0) - { - for (auto& err : errors) - { - vector splited; - splitString(err, '\n', splited); - for (auto& elem : splited) - { - if (elem.find("Error") != string::npos) - { - printf("%s\n", elem.c_str()); - code++; - } - } - } - } - - if (code == 0 && rethrow == 0) - { - FILE* proj = fopen("dvm.proj", "w"); - if (proj == NULL) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - for (auto& file : result.second) - fprintf(proj, "%s.dep\n", file.c_str()); - printf("Parsing was completed successfully\n"); - } - else - printf("Parsing was completed with errors, throw code %d, errors count %d\n", rethrow, code); - exit(0); - } + parseFiles(argc - (i + 1), argv + (i + 1)); else if (string(curr_arg) == "-mpi") mpiProgram = 1; else if (string(curr_arg) == "-pppa") diff --git a/sapfor/experts/Sapfor_2017/_src/SapforData.h b/sapfor/experts/Sapfor_2017/_src/SapforData.h index 7835946..d495e12 100644 --- a/sapfor/experts/Sapfor_2017/_src/SapforData.h +++ b/sapfor/experts/Sapfor_2017/_src/SapforData.h @@ -47,6 +47,7 @@ bool fullDepGraph = false; bool noLogo = false; bool withTemplateInfo = false; bool inlcudeAllFiles = false; // for pass INSERT_INLCUDES +bool runAsClient = false; // run console project as client for Visualizer uint64_t currentAvailMemory = 0; int QUALITY; // quality of conflicts search in graph diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp b/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp index fd45c3b..a395ec4 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.cpp @@ -23,6 +23,7 @@ #include #include #include + #ifdef _WIN32 #include #else @@ -58,30 +59,6 @@ using std::make_tuple; using std::wstring; using std::stack; -#ifdef _MSC_VER -#include -#define popen _popen -#define pclose _pclose -#define stat _stat -#define dup _dup -#define dup2 _dup2 -#define fileno _fileno -#define close _close -#define pipe _pipe -#define read _read -#define eof _eof -#else -#include -#endif - -#ifndef STD_OUT_FD -#define STD_OUT_FD (fileno(stdout)) -#endif - -#ifndef STD_ERR_FD -#define STD_ERR_FD (fileno(stderr)) -#endif - static bool ifIntervalExists(const vector> &intervals, const pair &toFind, pair& inInterval) { bool retVal = false; @@ -2768,903 +2745,6 @@ vector makeDeclaration(const vector& symbolsToDeclare, return allDecls; } -static void findModuleDeclInProject(const string &name, const vector &files, map &modDecls) -{ - char** filesList = new char* [files.size()]; - for (int z = 0; z < files.size(); ++z) - filesList[z] = (char*)files[z].c_str(); - - SgProject* tmpProj = new SgProject(name.c_str(), filesList, files.size()); - - int numF = tmpProj->numberOfFiles(); - set filesSg; - for (int z = 0; z < numF; ++z) - { - vector modules; - SgFile* currF = &tmpProj->file(z); - string fileName = currF->filename(); - convertToLower(fileName); - - filesSg.insert(currF); - - findModulesInFile(currF, modules); - for (auto& elem : modules) - { - if (string(elem->fileName()) == currF->filename()) - { - const string name = elem->symbol()->identifier(); - auto it = modDecls.find(name); - if (it != modDecls.end() && it->second != currF->filename()) - { - __spf_print(1, "found several module declaration of '%s' in files '%s' and '%s'\n", name.c_str(), it->second.c_str(), currF->filename()); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - else - modDecls.insert(it, make_pair(name, currF->filename())); - } - } - } - - delete[]filesList; - InitializeTable(); -} - -class StdCapture -{ -public: - static void Init() - { - // make stdout & stderr streams unbuffered - // so that we don't need to flush the streams - // before capture and after capture - // (fflush can cause a deadlock if the stream is currently being - std::lock_guard lock(m_mutex); - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - } - - static void BeginCapture() - { - std::lock_guard lock(m_mutex); - if (m_capturing) - return; - - secure_pipe(m_pipe); - m_oldStdOut = secure_dup(STD_OUT_FD); - m_oldStdErr = secure_dup(STD_ERR_FD); - secure_dup2(m_pipe[WRITE], STD_OUT_FD); - secure_dup2(m_pipe[WRITE], STD_ERR_FD); - m_capturing = true; -#ifndef _MSC_VER - secure_close(m_pipe[WRITE]); -#endif - } - static bool IsCapturing() - { - std::lock_guard lock(m_mutex); - return m_capturing; - } - static void EndCapture() - { - std::lock_guard lock(m_mutex); - if (!m_capturing) - return; - - m_captured.clear(); - secure_dup2(m_oldStdOut, STD_OUT_FD); - secure_dup2(m_oldStdErr, STD_ERR_FD); - - const int bufSize = 1025; - char buf[bufSize]; - int bytesRead = 0; - bool fd_blocked(false); - do - { - bytesRead = 0; - fd_blocked = false; -#ifdef _MSC_VER - if (!eof(m_pipe[READ])) - bytesRead = read(m_pipe[READ], buf, bufSize - 1); -#else - bytesRead = read(m_pipe[READ], buf, bufSize - 1); -#endif - if (bytesRead > 0) - { - buf[bytesRead] = 0; - m_captured += buf; - } - else if (bytesRead < 0) - { - fd_blocked = (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR); - if (fd_blocked) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } while (fd_blocked || bytesRead == (bufSize - 1)); - - secure_close(m_oldStdOut); - secure_close(m_oldStdErr); - secure_close(m_pipe[READ]); -#ifdef _MSC_VER - secure_close(m_pipe[WRITE]); -#endif - m_capturing = false; - } - static std::string GetCapture() - { - std::lock_guard lock(m_mutex); - return m_captured; - } -private: - enum PIPES { READ, WRITE }; - - static int secure_dup(int src) - { - int ret = -1; - bool fd_blocked = false; - do - { - ret = dup(src); - fd_blocked = (errno == EINTR || errno == EBUSY); - if (fd_blocked) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } while (ret < 0); - return ret; - } - static void secure_pipe(int* pipes) - { - int ret = -1; - bool fd_blocked = false; - do - { -#ifdef _MSC_VER - ret = pipe(pipes, 1024 * 1024 * 20, O_BINARY); // 20 MB -#else - ret = pipe(pipes) == -1; - fcntl(*pipes, F_SETPIPE_SZ, 1024 * 1024 * 20); -#endif - fd_blocked = (errno == EINTR || errno == EBUSY); - if (fd_blocked) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } while (ret < 0); - } - static void secure_dup2(int src, int dest) - { - int ret = -1; - bool fd_blocked = false; - do - { - ret = dup2(src, dest); - fd_blocked = (errno == EINTR || errno == EBUSY); - if (fd_blocked) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } while (ret < 0); - } - - static void secure_close(int& fd) - { - int ret = -1; - bool fd_blocked = false; - do - { - ret = close(fd); - fd_blocked = (errno == EINTR); - if (fd_blocked) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } while (ret < 0); - - fd = -1; - } - - static int m_pipe[2]; - static int m_oldStdOut; - static int m_oldStdErr; - static bool m_capturing; - static std::mutex m_mutex; - static std::string m_captured; -}; - -// actually define vars. -int StdCapture::m_pipe[2]; -int StdCapture::m_oldStdOut; -int StdCapture::m_oldStdErr; -bool StdCapture::m_capturing; -std::mutex StdCapture::m_mutex; -std::string StdCapture::m_captured; - -static vector splitAndArgvCreate(const string& options) -{ - vector optSplited; - optSplited.push_back(""); - splitString(options, ' ', optSplited, true); - - vector optSplited1; - for (auto& elem : optSplited) - if (elem != "") - optSplited1.push_back(elem); - optSplited1.insert(optSplited1.begin(), ""); - - for (int z = 0; z < optSplited1.size(); ++z) - { - //printf("%s\n", optSplited1[z].c_str()); - if (optSplited1[z][0] == '"' && optSplited1[z][optSplited1[z].size() - 1] == '"') - optSplited1[z] = optSplited1[z].substr(1, optSplited1[z].size() - 2); - } - return optSplited1; -} - -static void createIncludeOrder(vector &toIncl, - const map& moduleDelc, - const map>& modDirectOrder, - set &done, - const string &curr) -{ - if (done.find(curr) == done.end()) - { - for (auto& elem : modDirectOrder.find(curr)->second) - createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, elem); - - if (done.find(curr) == done.end()) - { - toIncl.push_back(moduleDelc.find(curr)->second); - done.insert(curr); - } - } -} - -static set applyModuleDeclsForFile(FileInfo *forFile, const map &mapFiles, - const map& moduleDelc, - const map>& mapModuleDeps, - const map>& modDirectOrder, - vector &optSplited, - bool includeForInline = false) -{ - set retFilesMod; - - auto itF = mapModuleDeps.find(forFile->fileName); - if (itF == mapModuleDeps.end() && !includeForInline) - return retFilesMod; - - vector toIncl; - set done; - if (itF != mapModuleDeps.end()) - { - for (auto& mod : itF->second) - if (moduleDelc.find(mod) != moduleDelc.end()) - createIncludeOrder(toIncl, moduleDelc, modDirectOrder, done, mod); - } - - //rewrite files to the next iter of parse - set allFiles; - bool needToConvertStyle = false; - for (auto& incl : toIncl) - { - if (mapFiles.find(incl) == mapFiles.end()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - allFiles.insert(mapFiles.find(incl)->second); - } - allFiles.insert(forFile); - - int style = forFile->style; - for (auto& elem : allFiles) - { - if (style != elem->style) - { - needToConvertStyle = true; - break; - } - } - - string mainText = forFile->text; - if (needToConvertStyle) - { - for (auto& elem : allFiles) - { - if (elem->style != 2) - { - retFilesMod.insert(elem); - if (elem != forFile) - auto tmp = convertStyle(elem); - else - mainText = convertStyle(elem, false); - } - } - - if (forFile->style != 2) - { - for (auto& opt : optSplited) - { - if (opt == "-FI" || opt == "-extend_source") - opt = "-FR"; - } - } - } - - string include = ""; - int includeCount = 0; - set included; - for (auto& incl : toIncl) - { - if (included.find(incl) == included.end()) - { - include += " include '" + incl + "'\n"; - includeCount++; - } - included.insert(incl); - } - - vector toInclEnds; - string includeLast = ""; - - if (includeForInline) - { - //find needed modules first - vector filesWithModules; - for (auto& elem : moduleDelc) - filesWithModules.push_back(elem.second); - for (auto& file : filesWithModules) - { - if (file != forFile->fileName && included.find(file) == included.end()) - { - toInclEnds.push_back(file); - included.insert(file); - } - } - - for (auto& file : mapFiles) - if (file.second != forFile && included.find(file.second->fileName) == included.end()) - toInclEnds.push_back(file.second->fileName); - - if (toInclEnds.size()) - includeLast += "!SPF SHADOW FILES\n"; - - for (auto& incl : toInclEnds) - includeLast += " include '" + incl + "'\n"; - } - - if (includeCount) - include = "!SPF NUM FILES " + std::to_string(includeCount) + "\n" + include; - - const string data = include + mainText + includeLast; - __spf_print(1, "include to file %s before\n", forFile->fileName.c_str()); - __spf_print(1, "%s", include.c_str()); - __spf_print(1, "include to file %s after\n", forFile->fileName.c_str()); - __spf_print(1, "%s", includeLast.c_str()); - - writeFileFromStr(forFile->fileName, data); - - forFile->includesAdded = included.size(); - forFile->includes = included; - - retFilesMod.insert(forFile); - return retFilesMod; -} - -static void restoreOriginalText(const vector& listOfProject) -{ - for (auto& elem : listOfProject) - writeFileFromStr(elem.fileName, elem.text); - fflush(NULL); -} - -static inline void restoreOriginalText(const FileInfo& file) -{ - writeFileFromStr(file.fileName, file.text); -} - -static void checkRetCode(FileInfo& info, const string& errorMessage) -{ - if (info.error != 0) - info.lvl++; - - if (errorMessage.find("Warning 308") != string::npos) - if (info.error == 0) - info.error = 1; -} - - -extern "C" int parse_file(int argc, char* argv[], char* proj_name); -static vector parseList(vector& listOfProject, - bool needToInclude, bool needToIncludeForInline, - const map> &mapModuleDeps, - const map &moduleDelc, - const map> &modDirectOrder, bool isFromConsole = false) -{ - map mapFiles; - for (auto& elem : listOfProject) - mapFiles[elem.fileName] = &elem; - - vector errors; - int i = 1; - int N = listOfProject.size(); - for (auto& elem : listOfProject) - { - sendMessage_progress(std::to_wstring((int)(((double)(i++) / N) * 100))); - - string file = elem.fileName; - string options = elem.options; - vector optSplited = splitAndArgvCreate(options); - - char** toParse = new char* [optSplited.size() + 1]; - for (int z = 0; z < optSplited.size(); ++z) - { - toParse[z] = new char[optSplited[z].size() + 1]; - strcpy(toParse[z], optSplited[z].c_str()); - } - toParse[optSplited.size()] = new char[file.size() + 1]; - strcpy(toParse[optSplited.size()], file.c_str()); - - if (options.find("-FI") != string::npos) - elem.style = 0; - else if (options.find("-FR") != string::npos || options.find("-f90") != string::npos) - elem.style = 2; - else if (options.find("-extend_source") != string::npos) - elem.style = 1; - - for (int z = 0; z < optSplited.size(); ++z) - { - if (optSplited[z] == "-o") - { - if (z + 1 == optSplited.size()) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - elem.outDepPath = optSplited[z + 1]; - break; - } - } - - FILE* depPath = fopen(elem.outDepPath.c_str(), "r"); - if (depPath && !isFromConsole) - { - fclose(depPath); - if (elem.error <= 0) - { - elem.error = 0; - errors.push_back(""); - for (int z = 0; z <= optSplited.size(); ++z) - delete toParse[z]; - delete[] toParse; - continue; - } - } - -#ifdef _WIN32 - sendMessage_2lvl(L" обработка файла '" + to_wstring(file) + L"'"); -#else - sendMessage_2lvl(L" processing file '" + to_wstring(file) + L"'"); -#endif - StdCapture::Init(); - string errorMessage = ""; - try - { - set filesModified; - StdCapture::BeginCapture(); - if (needToInclude) - filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline); - else if (needToIncludeForInline) // TODO for modules - filesModified = applyModuleDeclsForFile(&elem, mapFiles, moduleDelc, mapModuleDeps, modDirectOrder, optSplited, needToIncludeForInline); - - int retCode = parse_file(optSplited.size(), toParse, "dvm.proj"); - if (needToInclude || needToIncludeForInline) - { - for (auto &elem : filesModified) - restoreOriginalText(*elem); - fflush(NULL); - } - - elem.error = retCode; - StdCapture::EndCapture(); - errorMessage = StdCapture::GetCapture(); - checkRetCode(elem, errorMessage); - } - catch (int err) - { - StdCapture::EndCapture(); - errorMessage = StdCapture::GetCapture(); - - if (needToInclude || needToIncludeForInline) - restoreOriginalText(listOfProject); - } - catch (...) - { - StdCapture::EndCapture(); - errorMessage = StdCapture::GetCapture(); - - if (needToInclude || needToIncludeForInline) - restoreOriginalText(listOfProject); - } - errors.push_back(errorMessage); - for (int z = 0; z <= optSplited.size(); ++z) - delete toParse[z]; - delete[] toParse; - - createNeededException(); - } - return errors; -} - -static string shiftLines(const string &in, const map &mapOfFiles, const FileInfo* currF) -{ - int byNum = 0; - - auto it = in.find("on line "); - if (it != string::npos) - it += strlen("on line "); - - int d = 0; - sscanf(in.c_str() + it, "%d", &d); - - auto it1 = in.find("of", it + 1); - if (it1 == string::npos) - return in; - it1 += 3; - - string fileN = in.substr(it1, in.find(':', it1) - it1); - auto itF = mapOfFiles.find(fileN); - if (itF == mapOfFiles.end()) - return in; - if (itF->second != currF) - return in; - - byNum = itF->second->includesAdded; - if (byNum == 0) - return in; - - if (d - byNum <= 0) - { - //return in; - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - else - d -= byNum; - - string newStr = in.substr(0, it) + std::to_string(d) + in.substr(in.find(' ', it + 1)); - return newStr; -} - -static int dumpErrors(const vector& listOfProject, const vector& errors) -{ - int errorsCount = 0; - map mapOfFiles; - for (auto& elem : listOfProject) - mapOfFiles[elem.fileName] = &elem; - - int z = 0; - for (auto& file : listOfProject) - { - if (errors[z] == "") - { - FILE* ferr = fopen(file.errPath.c_str(), "w"); - if (!ferr) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - fclose(ferr); - ++z; - continue; - } - - FILE* ferr = fopen(file.errPath.c_str(), "w"); - FILE* fout = fopen(file.outPath.c_str(), "w"); - if (!ferr) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - if (!fout) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - string errS = "", outS = ""; - vector splited; - splitString(errors[z], '\n', splited); - for (auto& elem : splited) - { - if (elem.find("Warning 308") != string::npos) - outS += shiftLines(elem, mapOfFiles, &file) + "\n"; - else if (elem.find("Error") != string::npos) - { - errS += shiftLines(elem, mapOfFiles, &file) + "\n"; - errorsCount++; - } - } - - fprintf(fout, "%s", outS.c_str()); - fprintf(ferr, "%s", errS.c_str()); - - fflush(NULL); - - fclose(fout); - fclose(ferr); - ++z; - } - - return errorsCount; -} - -static int createMapOfUse(const vector& errors, const vector& listOfProject, map> &mapModuleDeps) -{ - int changed = 0; - for (int z = 0; z < listOfProject.size(); ++z) - { - if (listOfProject[z].error >= 0) - { - vector splited; - splitString(errors[z], '\n', splited); - for (auto& err : splited) - { - if (err.find("Warning 308") != string::npos && err.find(listOfProject[z].fileName) != string::npos) - { - auto pos = err.find("Unknown module"); - if (pos != string::npos) - { - pos += strlen("Unknown module") + 1; - string substr = ""; - while (err[pos] != ' ' && pos != err.size()) - substr += err[pos++]; - mapModuleDeps[listOfProject[z].fileName].insert(substr); - changed++; - } - } - } - } - } - - return changed; -} - -static map> createModuleOrder(const map &moduleDelc, const map> &mapModuleDeps) -{ - map> modDirectOrder; - for (auto& elem : moduleDelc) - modDirectOrder[elem.first] = set(); - - for (auto& elem : moduleDelc) - { - auto itF = mapModuleDeps.find(elem.second); - if (itF != mapModuleDeps.end()) - { - for (auto& inFile : itF->second) - { - if (moduleDelc.find(inFile) != moduleDelc.end()) - modDirectOrder[elem.first].insert(inFile); - } - } - } - - return modDirectOrder; -} - -static void printDebug(const map>& mapModuleDeps, const map>& modDirectOrder, - const vector& listOfProject, bool console = false) -{ - string toPrint = "MODULE DEPS:\n"; - for (auto& elem : mapModuleDeps) - { - toPrint += elem.first + '\n'; - for (auto& setEl : elem.second) - toPrint += " " + setEl + '\n'; - } - toPrint += "MODULE DIRECT ORDER:\n"; - for (auto& elem : modDirectOrder) - { - toPrint += elem.first + '\n'; - for (auto& setEl : elem.second) - toPrint += " " + setEl + '\n'; - } - toPrint += "FILES LVL:\n"; - for (auto& elem : listOfProject) - toPrint += elem.fileName + " " + elem.outDepPath + " lvl = " + std::to_string(elem.lvl) + '\n'; - if (console) - printf("%s\n", toPrint.c_str()); - __spf_print(1, "%s\n", toPrint.c_str()); -} - -int parseFiles(vector& errors, vector& listOfProject, vector& filesCompilationOrder, int parseForInlining, bool isFromConsole) -{ - int rethrow = 0; - int iters = 0; - int changed = 0; - int lastChanged = 0; - const string projName = "tmp"; - - map> mapModuleDeps; - map moduleDelc; - map> modDirectOrder; - - try - { - do - { -#ifdef _WIN32 - sendMessage_1lvl(L"выполняется " + std::to_wstring((iters + 1)) + L" итерация синтаксического анализа"); -#else - sendMessage_1lvl(L"running " + std::to_wstring((iters + 1)) + L" iteration of syntax analisys"); -#endif - errors = parseList(listOfProject, iters != 0, (parseForInlining != 0), mapModuleDeps, moduleDelc, modDirectOrder, isFromConsole); - changed = createMapOfUse(errors, listOfProject, mapModuleDeps); - if (iters != 0) - if (lastChanged <= changed) - break; - - createNeededException(); - - if (changed) - { - vector files; - for (auto& elem : listOfProject) - if (elem.error == 0) - files.push_back(elem.outDepPath); - if (files.size() == 0) - break; - findModuleDeclInProject(projName + std::to_string(iters++), files, moduleDelc); - modDirectOrder = createModuleOrder(moduleDelc, mapModuleDeps); - } - lastChanged = changed; - //printDebug(mapModuleDeps, modDirectOrder, listOfProject); - } while (changed); - - - //printDebug(mapModuleDeps, modDirectOrder, listOfProject); - - int added = 0; - int iter = 0; - vector files; - while (added != listOfProject.size()) - { - for (auto& elem : listOfProject) - { - if (elem.lvl == iter) - { - files.push_back(elem.fileName); - added++; - } - } - ++iter; - } - - map> fileDeps; - for (auto& file : files) - { - fileDeps[file] = set(); - if (mapModuleDeps.find(file) == mapModuleDeps.end()) - continue; - - for (auto& dep : mapModuleDeps[file]) - { - if (moduleDelc.find(dep) == moduleDelc.end()) - continue; - fileDeps[file].insert(moduleDelc[dep]); - } - } - - set addedFiles; - - added = 0; - while (added != fileDeps.size()) - { - for (auto& file : fileDeps) - { - bool depsAdded = true; - for (auto& dep : file.second) - if (addedFiles.find(dep) == addedFiles.end()) - depsAdded = false; - - if (depsAdded && addedFiles.find(file.first) == addedFiles.end()) - { - filesCompilationOrder.push_back(file.first); - addedFiles.insert(file.first); - added++; - } - } - } - - - __spf_print(1, "files compilation order:\n"); - for (auto& file : filesCompilationOrder) - __spf_print(1, " %s\n", file.c_str()); - } - catch (int err) - { - rethrow = err; - } - catch (...) - { - rethrow = -1; - } - return rethrow; -} - -int parseFiles(const char* proj, vector& filesCompilationOrder, int parseForInlining) -{ - FILE* list = fopen(proj, "r"); - if (!list) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - - vector pathSplit; - if (string(proj).find('\\') != string::npos) - splitString(proj, '\\', pathSplit); - else - splitString(proj, '/', pathSplit); - - if (pathSplit.size() < 2) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - if (pathSplit[pathSplit.size() - 2] != "visualiser_data") - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - string fullPath = ""; - for (int z = 0; z < pathSplit.size() - 2; ++z) - fullPath += pathSplit[z] + "/"; - if (fullPath == "") - fullPath = "./"; - else - { - //change dir - if (chdir(fullPath.c_str()) != 0) - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - - vector listOfProject; - while (!feof(list)) - { - char buf[1024]; - if (fgets(buf, 1024, list) == NULL) - continue; - - string toAdd = buf; - if (toAdd[toAdd.size() - 1] == '\n') - toAdd = toAdd.erase(toAdd.size() - 1); - - string fileNameFixed = ""; - auto idx = toAdd.find(fullPath); - if (idx != string::npos) - fileNameFixed = toAdd.substr(idx + fullPath.size()); - else - fileNameFixed = (toAdd.substr(0, 2) == "./") ? toAdd.substr(2) : toAdd; - - const string optPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".opt"; - const string errPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".err"; - const string outPath = fullPath + "visualiser_data/options/" + fileNameFixed + ".out"; - - const string fileText = readFileToStr(toAdd); - - FILE* opt = fopen(optPath.c_str(), "r"); - if (!opt) - { - __spf_print(1, "can not open path %s\n", optPath.c_str()); - printInternalError(convertFileName(__FILE__).c_str(), __LINE__); - } - fgets(buf, 1024, opt); - string toAddOpt = buf; - if (toAddOpt[toAddOpt.size() - 1] == '\n') - toAddOpt = toAddOpt.erase(toAddOpt.size() - 1); - - fclose(opt); - listOfProject.push_back(FileInfo(fileNameFixed, toAddOpt, errPath, outPath, "", fileText)); - } - - fclose(list); - vector errors; - - int rethrow = parseFiles(errors, listOfProject, filesCompilationOrder, parseForInlining); - int errCount = dumpErrors(listOfProject, errors); - - if (rethrow != 0) - throw rethrow; - return -errCount; -} - -extern int pppa_analyzer(int argv, char** argc); -int pppaAnalyzer(const char* options) -{ - string optionsS(options); - vector splited = splitAndArgvCreate(optionsS); - - char** argv = new char* [splited.size()]; - for (int z = 0; z < splited.size(); ++z) - argv[z] = (char*)splited[z].c_str(); - - StdCapture::Init(); - string errorMessage = ""; - int retCode = pppa_analyzer(splited.size(), argv); - StdCapture::EndCapture(); - errorMessage = StdCapture::GetCapture(); - - delete[]argv; - return retCode; -} - int getNextFreeLabel() { PTR_LABEL lab; diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.h b/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.h index b952a5b..0222d18 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/SgUtils.h @@ -74,11 +74,6 @@ std::string unparseProjectToString(SgFile* file, const int curr_regime); SgStatement* makeDeclaration(SgStatement* curr, const std::vector& s, std::vector* inits = NULL); std::vector makeDeclaration(const std::vector& symbolsToDeclare, SgStatement* where, std::vector* inits = NULL); -int parseFiles(const char* proj, std::vector& filesCompilationOrder, int parseForInlining); -int parseFiles(std::vector& errors, std::vector& listOfProject, std::vector& filesCompilationOrder, int parseForInlining, bool isFromConsole = false); - -int pppaAnalyzer(const char* options); - int getNextFreeLabel(); void fillUsedModulesInFunction(SgStatement *st, std::vector &useStats); @@ -111,4 +106,4 @@ void removeSpecialCommentsFromProject(SgFile* file); void getMaxMinBlockDistribution(SgFile* file, std::pair& min_max); -void addPrivatesToArraysFromGUI(SgFile* file, const std::map, std::pair>& declaredArrays, const std::map& distrStateFromGUI); \ No newline at end of file +void addPrivatesToArraysFromGUI(SgFile* file, const std::map, std::pair>& declaredArrays, const std::map& distrStateFromGUI); diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp b/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp index 303a273..90531e3 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp +++ b/sapfor/experts/Sapfor_2017/_src/Utils/utils.cpp @@ -150,7 +150,7 @@ void printHelp(const char **passNames, const int lastPass) printf(" -keepDVM keep DVM directives\n"); printf(" -allVars get all parallel versions\n"); printf(" -var N get specific parallel version, N=1,2,..\n"); - printf(" -parse run parser with next option\n"); + printf(" -parse run parser with next option (-inl option allow to parse project for -inlineH/I regime)\n"); printf(" -inlineH run hierarchical inlining for all functions called from 'funcName'\n"); printf(" -inlineI run incremental inlining for function 'funcName' on 'lineNum' of 'fileName'\n"); printf(" -passInfo print passes information\n"); @@ -1537,56 +1537,6 @@ wstring fixedLongFormat(const wchar_t* old_) return ret; } -string convertStyle(const FileInfo* file, bool needRewrite) -{ - string text = file->text; - - vector splited; - splitString(text, '\n', splited); - - text = ""; - int z = 0; - for (auto& line : splited) - { - if (line[0] == 'c' || line[0] == 'C' || line[0] == 'd' || line[0] == 'D' || line[0] == '*') - line[0] = '!'; - - bool needContinuation = false; - if (line[0] != '!' && line.size() > 6) - { - if (line[5] != ' ' && !(line[5] > '0' && line[5] < '9')) // not label - { - line[5] = ' '; - needContinuation = true;// line[5] = '&'; - } - - int p = 73; - if (file->style == 1) - p = 133; - if (line.size() > p) - { - while (line[p] != '\0' && line[p] != '\n' && line[p] != '!') - { - line[p] = ' '; - p++; - if (p >= line.size()) - break; - } - } - } - - if (needContinuation) - text += "&"; - text += (z != 0 ? "\n" : "") + line; - ++z; - } - - if (needRewrite) - writeFileFromStr(file->fileName, text); - - return text; -} - const set getExcludedModules() { return { "omp_lib", "ifport" }; }; map sortArraysByName(const set& toSort) @@ -1599,4 +1549,25 @@ map sortArraysByName(const set& toSort) printInternalError(convertFileName(__FILE__).c_str(), __LINE__); return sorted; -} \ No newline at end of file +} + +vector splitAndArgvCreate(const string& options) +{ + vector optSplited; + optSplited.push_back(""); + splitString(options, ' ', optSplited, true); + + vector optSplited1; + for (auto& elem : optSplited) + if (elem != "") + optSplited1.push_back(elem); + optSplited1.insert(optSplited1.begin(), ""); + + for (int z = 0; z < optSplited1.size(); ++z) + { + //printf("%s\n", optSplited1[z].c_str()); + if (optSplited1[z][0] == '"' && optSplited1[z][optSplited1[z].size() - 1] == '"') + optSplited1[z] = optSplited1[z].substr(1, optSplited1[z].size() - 2); + } + return optSplited1; +} diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/utils.h b/sapfor/experts/Sapfor_2017/_src/Utils/utils.h index d3643d9..e878329 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/utils.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/utils.h @@ -87,50 +87,6 @@ std::pair, std::vector> splitCommandLineFo std::string getClearName(const std::string& in); std::wstring fixedLongFormat(const wchar_t* old); -struct FileInfo -{ - FileInfo() - { - fileName = ""; - options = ""; - errPath = ""; - outPath = ""; - outDepPath = ""; - text = ""; - error = -1; - includesAdded = 0; - style = -1; - lvl = 0; - } - - FileInfo(const std::string& _fileName, const std::string& _options, const std::string& _errPath, const std::string& _outPath, - const std::string& _outDepPath, const std::string& _text, int errorInit = -1) - { - fileName = _fileName; - options = _options; - errPath = _errPath; - outPath = _outPath; - outDepPath = _outDepPath; - text = _text; - error = errorInit; - includesAdded = 0; - style = -1; - lvl = 0; - } - - int error; - std::string fileName; - std::string options; - std::string errPath; - std::string outPath; - std::string outDepPath; - std::string text; - int style; // -1 unk, 0 fixed, 1 fixed ext, 2 free - int includesAdded; - std::set includes; - int lvl; -}; - -std::string convertStyle(const FileInfo* file, bool needRewrite = true); std::map sortArraysByName(const std::set& toSort); -bool createDirectory(const std::string& name); \ No newline at end of file +bool createDirectory(const std::string& name); +std::vector splitAndArgvCreate(const std::string& options); diff --git a/sapfor/experts/Sapfor_2017/_src/Utils/version.h b/sapfor/experts/Sapfor_2017/_src/Utils/version.h index 1a06b02..855d4b4 100644 --- a/sapfor/experts/Sapfor_2017/_src/Utils/version.h +++ b/sapfor/experts/Sapfor_2017/_src/Utils/version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_SPF "2275" +#define VERSION_SPF "2276" diff --git a/sapfor/experts/Sapfor_2017/_src/VisualizerCalls/get_information.cpp b/sapfor/experts/Sapfor_2017/_src/VisualizerCalls/get_information.cpp index 6ec8dd9..eadc920 100644 --- a/sapfor/experts/Sapfor_2017/_src/VisualizerCalls/get_information.cpp +++ b/sapfor/experts/Sapfor_2017/_src/VisualizerCalls/get_information.cpp @@ -40,6 +40,8 @@ #include "../Distribution/CreateDistributionDirs.h" #include "../LoopAnalyzer/loop_analyzer.h" #include "../DirectiveProcessing/insert_directive.h" +#include "../ProjectManipulation/PerfAnalyzer.h" + #include "BuildGraph.h" #ifdef _WIN32