vector<string> lookup_argument(const string& argument) { using boost::iequals; vector<string> args; if (iequals(argument, "int")) { args.push_back("int"); } else if (iequals(argument, "ints")) { args.push_back("int"); args.push_back("std::vector<int>"); args.push_back("Eigen::Matrix<int, Eigen::Dynamic, 1>"); args.push_back("Eigen::Matrix<int, 1, Eigen::Dynamic>"); } else if (iequals(argument, "double")) { args.push_back("double"); args.push_back("var"); } else if (iequals(argument, "doubles")) { args.push_back("double"); args.push_back("std::vector<double>"); args.push_back("Eigen::Matrix<double, Eigen::Dynamic, 1>"); args.push_back("Eigen::Matrix<double, 1, Eigen::Dynamic>"); args.push_back("var"); args.push_back("std::vector<var>"); args.push_back("Eigen::Matrix<var, Eigen::Dynamic, 1>"); args.push_back("Eigen::Matrix<var, 1, Eigen::Dynamic>"); } return args; }
void Gatekeeper::Handle() { std::stringstream r(message_); std::string s; r >> s; if( iequals( s, "GIV" ) ) { std::getline(r, s); const std::size_t pos = s.find(':'); std::string hex = s.substr(pos + 1, 2 * 16); GUID guid; assert(hex.size() == 32); Conv::Hex::Decode(hex.begin(), hex.end(), guid.begin()); std::vector< DownloadPtr > v; System::GetDownloadMgr()->Dump(std::back_inserter(v)); for(uint i = 0; i < v.size(); ++i) if(v[i]->HandleGIV(this, guid)) break; return; } else if(iequals(s, "GET")) { if(message_.find("\r\n\r\n") == std::string::npos) throw MessageIncomplete(); System::GetUploadMgr()->Accept(this); } else throw std::runtime_error("Unhandled"); }
bool FortranProgramDeclarationsAndDefinitions::checkModuleExists ( std::string const & moduleName) { using boost::iequals; using std::string; using std::map; using std::vector; bool found = false; for (map <string, vector <string> >::const_iterator it = fileNameToModuleNames.begin (); it != fileNameToModuleNames.end (); ++it) { string fileName = it->first; vector <string> moduleNames = it->second; for (vector <string>::const_iterator vectorIt = moduleNames.begin (); vectorIt != moduleNames.end (); ++vectorIt) { if (iequals (*vectorIt, moduleName)) { found = true; } } } return found; }
SgType * FortranProgramDeclarationsAndDefinitions::getTypeFromString (std::string const & opDataBaseTypeString, std::string const & variableName) { using namespace SageBuilder; using boost::iequals; if ( iequals(opDataBaseTypeString, OP2::FortranSpecific::PrimitiveTypes::real8) ) return buildDoubleType (); else if ( iequals(opDataBaseTypeString, OP2::FortranSpecific::PrimitiveTypes::real4) ) return buildFloatType (); else if ( iequals(opDataBaseTypeString, OP2::FortranSpecific::PrimitiveTypes::integer4) ) return buildIntType (); else throw Exceptions::ParallelLoop::UnsupportedBaseTypeException ("Bad type specified for GENERIC OP_DAT '" + variableName + "' "); }
void UploaderImp::TranslateRequest() { std::istream s( &request_ ); std::string line; s >> line; //method if( line == "GET" ) method_ = GET; else if( line == "HEAD" ) method_ = HEAD; else throw Unhandled(400, "Unknown method" ); s >> line; //object if( !starts_with( line, "/uri-res/N2R?" ) ) throw Unhandled(400, "Requested uri type is not supported"); std::string last = urn_; urn_ = line.substr(line.find('?') + 1); fileInfo_ = System::GetShareMgr()->GetByUrn( urn_ ); if(last != urn_) { System::LogBas() << "Host " << endpoint_ << " requested file: " << fileInfo_.Name() << std::endl; fileInfo_.IncreaseRequests(); } while( std::getline( s, line ) && line != "\r" ) { std::string value = boost::trim_copy( line.substr( line.find( ':' ) + 1 ) ); if( istarts_with( line, "Connection:" ) ) keepAlive_ = iequals( value, "keep-alive" ); else if( istarts_with( line, "X-Nick:" ) ) nick_ = value; else if(istarts_with(line, "User-Agent:") && client_ != value) { client_ = value; if(System::GetSecurity()->AgentRestricted(client_)) throw Unhandled(403, "Client software is restricted"); } else if( istarts_with( line, "Range:" ) ) { file_offset_t first = 0; file_offset_t last = 0; int result = sscanf( value.c_str(), "bytes=%llu-%llu", &first, &last ); if( result == 0 ) throw Unhandled(416, "Couldn't parse range"); if( result == 1 ) range_.SetBoundary( first, fileInfo_.Size() - 1); if( result == 2 ) range_.SetBoundary( first, last ); } } if( range_.Empty() ) throw std::range_error( "Range is empty" ); // std::cout << range_.Last() << " " << fileInfo.Size() << std::endl; if( range_.Last() >= fileInfo_.Size() ) throw Unhandled(416, "Range is too large" ); }
LASPointReader::LASPointReader(string path){ this->path = path; if(fs::is_directory(path)){ // if directory is specified, find all las and laz files inside directory for(fs::directory_iterator it(path); it != fs::directory_iterator(); it++){ fs::path filepath = it->path(); if(fs::is_regular_file(filepath)){ if(iequals(fs::extension(filepath), ".las") || iequals(fs::extension(filepath), ".laz")){ files.push_back(filepath.string()); } } } }else{ files.push_back(path); } // read bounding box for(int i = 0; i < files.size(); i++){ string file = files[i]; LIBLASReader aabbReader(file); AABB lAABB = aabbReader.getAABB(); aabb.update(lAABB.min); aabb.update(lAABB.max); aabbReader.close(); } // open first file currentFile = files.begin(); reader = new LIBLASReader(*currentFile); // cout << "let's go..." << endl; }
virtual void visit (SgNode * node) { using boost::iequals; using boost::filesystem::path; using boost::filesystem::system_complete; SgSourceFile * file = isSgSourceFile (node); if (file != NULL) { path p = system_complete (path (file->getFileName ())); if (generator->isDirty (p.filename ())) { Debug::getInstance ()->debugMessage ("Unparsing '" + p.filename () + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); outputFiles.push_back ("rose_" + p.filename ()); file->unparse (); } else if (iequals (p.filename (), generator->getFileName ())) { Debug::getInstance ()->debugMessage ("Unparsing generated file '" + p.filename () + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); outputFiles.push_back (p.filename ()); generatedFile = p.filename (); file->unparse (); } else { Debug::getInstance ()->debugMessage ("File '" + p.filename () + "' remains unchanged", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); outputFiles.push_back ("rose_" + p.filename ()); file->unparse (); } } }
void FortranCUDAUserSubroutine::createStatements () { using namespace SageInterface; using boost::iequals; using std::string; using std::vector; class TreeVisitor: public AstSimpleProcessing { private: /* * ====================================================== * The recursive visit of a user subroutine populates * this vector with successive function calls which are * then appended after the visit * ====================================================== */ vector < SgProcedureHeaderStatement * > calledRoutines; public: vector < SgProcedureHeaderStatement * > getCalledRoutinesInStatement() { return calledRoutines; } TreeVisitor () { } virtual void visit (SgNode * node) { SgExprStatement * isExprStatement = isSgExprStatement ( node ); if ( isExprStatement != NULL ) { SgFunctionCallExp * functionCallExp = isSgFunctionCallExp ( isExprStatement->get_expression() ); if ( functionCallExp != NULL ) { string const calleeName = functionCallExp->getAssociatedFunctionSymbol ()->get_name ().getString (); Debug::getInstance ()->debugMessage ("Found function call in user subroutine " + calleeName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); /* * ====================================================== * As we are in fortran, all user subroutines must be * SgProcedureHeaderStatements = subroutines and not * functions. This might be extended to cover also * functions in the future (?). Probably not in OP2 * ====================================================== */ SgProcedureHeaderStatement * isProcedureHeaderStatement = isSgProcedureHeaderStatement ( functionCallExp->getAssociatedFunctionDeclaration() ); calledRoutines.push_back ( isProcedureHeaderStatement ); } } } }; Debug::getInstance ()->debugMessage ("User subroutine: outputting and modifying statements", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); SgFunctionParameterList * originalParameters = originalSubroutine->get_parameterList (); vector <SgStatement *> originalStatements = originalSubroutine->get_definition ()->get_body ()->get_statements (); for (vector <SgStatement *>::iterator it = originalStatements.begin (); it != originalStatements.end (); ++it) { SgExprStatement * isExprStatement = isSgExprStatement ( *it ); if ( isExprStatement != NULL ) { SgFunctionCallExp * functionCallExp = isSgFunctionCallExp ( isExprStatement->get_expression() ); if ( functionCallExp != NULL ) { string const calleeName = functionCallExp->getAssociatedFunctionSymbol ()->get_name ().getString (); Debug::getInstance ()->debugMessage ("Found function call in user subroutine " + calleeName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); /* * ====================================================== * As we are in fortran, all user subroutines must be * SgProcedureHeaderStatements = subroutines and not * functions. This might be extended to cover also * functions in the future (probably not in OP2) * ====================================================== */ SgProcedureHeaderStatement * isProcedureHeaderStatement = isSgProcedureHeaderStatement ( functionCallExp->getAssociatedFunctionDeclaration() ); calledRoutines.push_back ( isProcedureHeaderStatement ); } } SgVariableDeclaration * isVariableDeclaration = isSgVariableDeclaration ( *it); if (isVariableDeclaration == NULL) { /* * ====================================================== * Do not append use statement, because other subroutines * are directly appended to the CUDA module * ====================================================== */ SgUseStatement * isUseStmt = isSgUseStatement ( *it ); if (isUseStmt != NULL) { Debug::getInstance ()->debugMessage ( "Not appending use statement", Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); } else { Debug::getInstance ()->debugMessage ( "Appending (non-variable-declaration) statement", Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); appendStatement (*it, subroutineScope); /* * ====================================================== * Recursively look for subroutine calls inside shallow * nodes in the routines (e.g. when a call is inside an * if). After the visit get the generated vector of names * and append it to the userSubroutine vector * ====================================================== */ TreeVisitor * visitor = new TreeVisitor (); visitor->traverse (*it, preorder); Debug::getInstance ()->debugMessage ("Appending deep subroutine calls", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); vector < SgProcedureHeaderStatement * > deepStatementCalls = visitor->getCalledRoutinesInStatement (); vector < SgProcedureHeaderStatement * >::iterator itDeepCalls; for (itDeepCalls = deepStatementCalls.begin(); itDeepCalls != deepStatementCalls.end(); ++itDeepCalls) calledRoutines.push_back (*itDeepCalls); Debug::getInstance ()->debugMessage ("Appending deep subroutine calls", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); } } else { Debug::getInstance ()->debugMessage ("Appending variable declaration", Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); unsigned int OP_DAT_ArgumentGroup = 1; for (SgInitializedNamePtrList::iterator variableIt = isVariableDeclaration->get_variables ().begin (); variableIt != isVariableDeclaration->get_variables ().end (); ++variableIt) { string const variableName = (*variableIt)->get_name ().getString (); SgType * type = (*variableIt)->get_typeptr (); /* * ====================================================== * Specification of "value" attribute is only * for user kernels. Our call convention is that * in all deeper level calls we always pass parameters * by reference (see else branch below) * ====================================================== */ bool isFormalParamater = false; for (SgInitializedNamePtrList::iterator paramIt = originalParameters->get_args ().begin (); paramIt != originalParameters->get_args ().end (); ++paramIt, ++OP_DAT_ArgumentGroup) { string const formalParamterName = (*paramIt)->get_name ().getString (); if (iequals (variableName, formalParamterName)) { isFormalParamater = true; if (parallelLoop->isIndirect (OP_DAT_ArgumentGroup) && parallelLoop->isRead (OP_DAT_ArgumentGroup)) { Debug::getInstance ()->debugMessage ("'" + variableName + "' is an INDIRECT formal parameter which is READ", Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); SgVariableDeclaration * variableDeclaration; if ( isUserKernel == true ) variableDeclaration = FortranStatementsAndExpressionsBuilder::appendVariableDeclarationAsFormalParameter ( variableName, type, subroutineScope, formalParameters, 0); else variableDeclaration = FortranStatementsAndExpressionsBuilder::appendVariableDeclarationAsFormalParameter ( variableName, type, subroutineScope, formalParameters, 0); ROSE_ASSERT ( variableDeclaration != NULL ); } else if (parallelLoop->isGlobal (OP_DAT_ArgumentGroup) && parallelLoop->isRead (OP_DAT_ArgumentGroup)) { Debug::getInstance ()->debugMessage ("'" + variableName + "' is a GLOBAL formal parameter which is READ", Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); SgVariableDeclaration * variableDeclaration = FortranStatementsAndExpressionsBuilder::appendVariableDeclarationAsFormalParameter ( variableName, type, subroutineScope, formalParameters, 0); } else { Debug::getInstance ()->debugMessage ("'" + variableName + "' is a formal parameter " + parallelLoop->getOpDatInformation (OP_DAT_ArgumentGroup), Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); if ( isUserKernel == true ) SgVariableDeclaration * variableDeclaration = FortranStatementsAndExpressionsBuilder::appendVariableDeclarationAsFormalParameter ( variableName, type, subroutineScope, formalParameters, 0); else SgVariableDeclaration * variableDeclaration = FortranStatementsAndExpressionsBuilder::appendVariableDeclarationAsFormalParameter ( variableName, type, subroutineScope, formalParameters, 0); } } } if (isFormalParamater == false) { Debug::getInstance ()->debugMessage ("'" + variableName + "' is NOT a formal parameter", Debug::HIGHEST_DEBUG_LEVEL, __FILE__, __LINE__); SgVariableDeclaration * variableDeclaration = FortranStatementsAndExpressionsBuilder::appendVariableDeclaration ( variableName, type, subroutineScope); } } } } }
/* * ====================================================== * This function appends all additional subroutines * called inside the user subroutine. It is specialised * for CUDA in the related subclass * ====================================================== */ void FortranCUDAUserSubroutine::appendAdditionalSubroutines ( SgScopeStatement * moduleScope, FortranParallelLoop * parallelLoop, FortranProgramDeclarationsAndDefinitions * declarations, FortranConstantDeclarations * CUDAconstants, std::vector < SgProcedureHeaderStatement * > * allCalledRoutines) { using std::vector; using boost::iequals; /* * ====================================================== * First removes duplicates in calledRoutines itself * ====================================================== */ sort ( calledRoutines.begin(), calledRoutines.end() ); calledRoutines.erase ( unique ( calledRoutines.begin(), calledRoutines.end() ), calledRoutines.end() ); Debug::getInstance ()->debugMessage ("Before removing, the list of routine calls found in the user kernels is: ", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); vector < SgProcedureHeaderStatement * > :: iterator routinesIt2; for ( routinesIt2 = calledRoutines.begin (); routinesIt2 != calledRoutines.end (); routinesIt2++ ) { string appendingSubroutine = (*routinesIt2)->get_name ().getString (); Debug::getInstance ()->debugMessage (appendingSubroutine, Debug::FUNCTION_LEVEL, __FILE__, __LINE__); } /* * ====================================================== * The removes routines already appended by other user * kernels, using the list in allCalledRoutines * ====================================================== */ Debug::getInstance ()->debugMessage ("Removing global duplicates, the number of routines in the list is: '" + boost::lexical_cast<string> ((int) calledRoutines.size()) + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); vector < SgProcedureHeaderStatement * > :: iterator routinesIt; for ( routinesIt = calledRoutines.begin (); routinesIt != calledRoutines.end (); ) //routinesIt++ ) { string appendingSubroutine = (*routinesIt)->get_name ().getString (); Debug::getInstance ()->debugMessage ("Checking routine for deletion: '" + appendingSubroutine + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); bool foundAndErased = false; vector < SgProcedureHeaderStatement * > :: iterator finder; for ( finder = allCalledRoutines->begin (); finder != allCalledRoutines->end (); finder++ ) { Debug::getInstance ()->debugMessage ("Checking against: '" + (*finder)->get_name ().getString () + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); if ( iequals ((*finder)->get_name ().getString (), appendingSubroutine) ) { /* * ====================================================== * Routine already appended by another user kernel: * delete it from list of routines to be appended for * this user kernel, and exit this loop * ====================================================== */ Debug::getInstance ()->debugMessage ("Deleting: '" + appendingSubroutine + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); calledRoutines.erase (routinesIt++); if ( calledRoutines.empty () ) return; foundAndErased = true; routinesIt--; break; } } if ( foundAndErased == false ) { /* * ====================================================== * New routine: it must be added to the list of * routines called by all previous user kernels because * recursively called routines need to discard those * already appended by this routine * ====================================================== */ Debug::getInstance ()->debugMessage ("Not found, appending: '" + appendingSubroutine + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); allCalledRoutines->push_back ( *routinesIt ); routinesIt++; } } vector < SgProcedureHeaderStatement * > :: iterator it; for ( it = calledRoutines.begin(); it != calledRoutines.end(); it++ ) { string calledSubroutineName = (*it)->get_name ().getString (); Debug::getInstance ()->debugMessage ("Appending new subroutine '" + calledSubroutineName + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); FortranCUDAUserSubroutine * newRoutine = new FortranCUDAUserSubroutine ( moduleScope, parallelLoop, declarations, calledSubroutineName ); newRoutine->createFormalParameterDeclarations (); newRoutine->createStatements (); additionalSubroutines.push_back (newRoutine); } vector < FortranUserSubroutine * > :: iterator itRecursive; for ( itRecursive = additionalSubroutines.begin(); itRecursive != additionalSubroutines.end(); itRecursive++ ) { FortranCUDAUserSubroutine * cudaSubroutineCasting = (FortranCUDAUserSubroutine *) *itRecursive; CUDAconstants->patchReferencesToConstants ( (cudaSubroutineCasting )->getSubroutineHeaderStatement ()); RoseHelper::forceOutputOfCodeToFile ( (cudaSubroutineCasting )->getSubroutineHeaderStatement ()); } for ( itRecursive = additionalSubroutines.begin(); itRecursive != additionalSubroutines.end(); itRecursive++ ) { FortranCUDAUserSubroutine * cudaSubroutineCasting = (FortranCUDAUserSubroutine *) *itRecursive; cudaSubroutineCasting->appendAdditionalSubroutines (moduleScope, parallelLoop, declarations, CUDAconstants, allCalledRoutines); } }
void FortranProgramDeclarationsAndDefinitions::visit (SgNode * node) { using boost::filesystem::path; using boost::filesystem::system_complete; using boost::iequals; using boost::starts_with; using boost::lexical_cast; using std::string; if (isSgSourceFile (node)) { path p = system_complete (path (isSgSourceFile (node)->getFileName ())); currentSourceFile = p.filename (); Debug::getInstance ()->debugMessage ("Source file '" + currentSourceFile + "' detected", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__ ); } else if (Globals::getInstance ()->isInputFile (currentSourceFile)) { /* * ====================================================== * Only process this portion of the AST if we recognise * this source file as one passed on the command line. In * Fortran, .rmod files are sometimes generated whose * traversal should be avoided * ====================================================== */ switch (node->variantT ()) { case V_SgModuleStatement: { SgModuleStatement * moduleStatement = isSgModuleStatement (node); currentModuleName = moduleStatement->get_name ().getString (); fileNameToModuleNames[currentSourceFile].push_back (currentModuleName); moduleNameToFileName[currentModuleName] = currentSourceFile; Debug::getInstance ()->debugMessage ("Module '" + currentModuleName + "' in file '" + currentSourceFile + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__ ); break; } case V_SgProcedureHeaderStatement: { /* * ====================================================== * We need to store all subroutine definitions since we * later have to copy and modify the user kernel subroutine * ====================================================== */ SgProcedureHeaderStatement * procedureHeaderStatement = isSgProcedureHeaderStatement (node); string const subroutineName = procedureHeaderStatement->get_name ().getString (); subroutinesInSourceCode[subroutineName] = procedureHeaderStatement; ROSE_ASSERT (currentModuleName.size() > 0); moduleNameToSubroutines[currentModuleName].push_back (subroutineName); subroutineToFileName[subroutineName] = currentSourceFile; Debug::getInstance ()->debugMessage ( "Found procedure header statement '" + procedureHeaderStatement->get_name ().getString () + "' in file '" + currentSourceFile + "', and module '" + currentModuleName + "'", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); break; } case V_SgFunctionCallExp: { /* * ====================================================== * Function call found in the AST. Get its actual arguments * and the callee name * ====================================================== */ SgFunctionCallExp * functionCallExp = isSgFunctionCallExp (node); SgExprListExp * actualArguments = functionCallExp->get_args (); string const calleeName = functionCallExp->getAssociatedFunctionSymbol ()->get_name ().getString (); Debug::getInstance ()->debugMessage ("Found function call '" + calleeName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); if ( iequals (calleeName, OP2::OP_DECL_SET) || iequals (calleeName, OP2::OP_DECL_SET_HDF5) ) { /* * ====================================================== * An OP_SET variable declared through an OP_DECL_SET call * ====================================================== */ bool isHDF5Format = false; if ( iequals (calleeName, OP2::OP_DECL_SET_HDF5) ) isHDF5Format = true; FortranOpSetDefinition * opSetDeclaration = new FortranOpSetDefinition (actualArguments, isHDF5Format); OpSetDefinitions[opSetDeclaration->getVariableName ()] = opSetDeclaration; } else if ( iequals (calleeName, OP2::OP_DECL_MAP) || iequals (calleeName, OP2::OP_DECL_MAP_HDF5) ) { /* * ====================================================== * An OP_MAP variable declared through an OP_DECL_MAP call * ====================================================== */ bool isHDF5Format = false; if ( iequals (calleeName, OP2::OP_DECL_MAP_HDF5) ) { isHDF5Format = true; Debug::getInstance ()->debugMessage ("This is the HDF5 version: '" + calleeName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); } FortranOpMapDefinition * opMapDeclaration = new FortranOpMapDefinition (actualArguments, isHDF5Format); OpMapDefinitions[opMapDeclaration->getVariableName ()] = opMapDeclaration; } else if ( iequals (calleeName, OP2::OP_DECL_DAT) || iequals (calleeName, OP2::OP_DECL_DAT_HDF5) ) { /* * ====================================================== * An OP_DAT variable declared through an OP_DECL_DAT call * ====================================================== */ bool isHDF5Format = false; if ( iequals (calleeName, OP2::OP_DECL_DAT_HDF5) ) isHDF5Format = true; FortranOpDatDefinition * opDatDeclaration = new FortranOpDatDefinition (actualArguments, isHDF5Format); OpDatDefinitions[opDatDeclaration->getVariableName ()] = opDatDeclaration; } else if (iequals (calleeName, OP2::OP_DECL_CONST)) { /* * ====================================================== * A constant declared through an OP_DECL_CONST call * ====================================================== */ FortranOpConstDefinition * opConstDeclaration = new FortranOpConstDefinition (actualArguments, functionCallExp); OpConstDefinitions[opConstDeclaration->getVariableName ()] = opConstDeclaration; } else if (starts_with (calleeName, OP2::OP_PAR_LOOP)) { /* * ====================================================== * The first argument to an 'OP_PAR_LOOP' call should be * a reference to the kernel function. Cast it and proceed, * otherwise throw an exception * ====================================================== */ SgExprListExp * actualArguments = functionCallExp->get_args (); SgFunctionRefExp * functionRefExpression = isSgFunctionRefExp ( actualArguments->get_expressions ().front ()); ROSE_ASSERT (functionRefExpression != NULL); string const userSubroutineName = functionRefExpression->getAssociatedFunctionDeclaration ()->get_name ().getString (); Debug::getInstance ()->debugMessage ("Found '" + calleeName + "' with (host) user subroutine '" + userSubroutineName + "'", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); if (parallelLoops.find (userSubroutineName) == parallelLoops.end ()) { int numberOfOpArgs = getLoopSuffixNumber ( calleeName ); /* * ====================================================== * If this kernel has not been previously encountered then * build a new parallel loop representation * ====================================================== */ FortranParallelLoop * parallelLoop = new FortranParallelLoop ( functionCallExp); parallelLoop->addFileName (currentSourceFile); parallelLoops[userSubroutineName] = parallelLoop; Debug::getInstance ()->debugMessage ("Parallel loop with '" + lexical_cast <string> (numberOfOpArgs) + "' arguments", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); analyseParallelLoopArguments (parallelLoop, actualArguments, numberOfOpArgs); parallelLoop->checkArguments (); parallelLoop->setIncrementalID (IDCounter); IDCounter++; } else { Debug::getInstance ()->debugMessage ("Parallel loop for '" + userSubroutineName + "' already created", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); ParallelLoop * parallelLoop = parallelLoops[userSubroutineName]; parallelLoop->addFunctionCallExpression (functionCallExp); parallelLoop->addFileName (currentSourceFile); } } break; } default: { break; } } } }
void FortranProgramDeclarationsAndDefinitions::analyseParallelLoopArguments ( FortranParallelLoop * parallelLoop, SgExprListExp * actualArguments, int numberOfOpArgs) { using boost::iequals; using boost::lexical_cast; using std::find; using std::string; using std::vector; using std::map; Debug::getInstance ()->debugMessage ( "Analysing OP_PAR_LOOP actual arguments", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); unsigned int OP_DAT_ArgumentGroup = 1; /* * ====================================================== * Loops over the arguments to populate the parallel loop object * Each object in the actualArguments array is a function call * We analyse the arguments of each call * \warning: the args start from position 2 (the first two args are * the user kernel reference and the iteration set * ====================================================== */ for ( int i = 2; i < numberOfOpArgs + 2; i++ ) { /* * ====================================================== * Distinguish between op_dat and global variable by * checking the function name * ====================================================== */ SgFunctionCallExp * functionExpression = isSgFunctionCallExp ( actualArguments->get_expressions ()[i]); ROSE_ASSERT (functionExpression != NULL); string functionName = functionExpression ->getAssociatedFunctionSymbol ()-> get_name ().getString (); SgExprListExp * opArgArguments = functionExpression ->get_args (); ROSE_ASSERT (opArgArguments ); /* * ====================================================== * Assume that this is not an op_mat, possibly amend later * ====================================================== */ parallelLoop->setIsOpMatArg (OP_DAT_ArgumentGroup, false); if ( functionName == "op_arg_dat" ) { /* * ====================================================== * Obtain the op_dat reference and its name * ====================================================== */ SgVarRefExp * opDatReference = NULL; opDatReference = getOpDatReferenceFromOpArg (opArgArguments); ROSE_ASSERT (opDatReference != NULL); string const opDatName = opDatReference->get_symbol ()->get_name ().getString (); /* * ====================================================== * Obtain the map reference and name, and select access * type (direct or indirect) * ====================================================== */ SgVarRefExp * opMapReference; opMapReference = getOpMapReferenceFromOpArg (opArgArguments); ROSE_ASSERT (opMapReference != NULL); string const mappingValue = opMapReference->get_symbol ()->get_name ().getString (); if (iequals (mappingValue, OP2::OP_ID)) { /* * ====================================================== * OP_ID signals identity mapping and therefore direct * access to the data * ====================================================== */ Debug::getInstance ()->debugMessage ("...DIRECT mapping descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, DIRECT); } else { Debug::getInstance ()->debugMessage ("...INDIRECT mapping descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, INDIRECT); } setOpDatProperties (parallelLoop, opDatName, OP_DAT_ArgumentGroup); setParallelLoopAccessDescriptor (parallelLoop, opArgArguments, OP_DAT_ArgumentGroup, DAT_ACC_POSITION); } else if ( functionName == "op_arg_gbl" ) { Debug::getInstance ()->debugMessage ("...GLOBAL mapping descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); /* * ====================================================== * Get the OP_GBL variable reference and name * ====================================================== */ SgVarRefExp * opDatReference; if (isSgDotExp (opArgArguments->get_expressions ()[DAT_POSITION]) != NULL) { opDatReference = isSgVarRefExp ( isSgDotExp ( opArgArguments->get_expressions ()[DAT_POSITION])->get_rhs_operand ()); } else { opDatReference = isSgVarRefExp ( opArgArguments->get_expressions ()[DAT_POSITION]); } string const globalName = opDatReference->get_symbol ()->get_name ().getString (); /* * ====================================================== * Get the OP_GBL dimension: check the number of args * to the op_arg_gbl function (3 = array, 2 = scalar) * ====================================================== */ if ( opArgArguments->get_expressions ().size () == GBL_SCALAR_ARG_NUM ) { Debug::getInstance ()->debugMessage ("'" + globalName + "' is a scalar", Debug::FUNCTION_LEVEL, __FILE__, __LINE__); /* * ====================================================== * Since this is a scalar, set the dimension to 1 * ====================================================== */ parallelLoop->setOpDatDimension (OP_DAT_ArgumentGroup, 1); } else { SgIntVal * intValExp = isSgIntVal (opArgArguments->get_expressions ()[GBL_DIM_POSITION]); ROSE_ASSERT (intValExp != NULL); int globalDimension = intValExp->get_value (); parallelLoop->setOpDatDimension (OP_DAT_ArgumentGroup, globalDimension); Debug::getInstance ()->debugMessage ("'" + globalName + "' is NOT a scalar, but has dimension " + lexical_cast<string> (globalDimension), Debug::FUNCTION_LEVEL, __FILE__, __LINE__); } /* * ====================================================== * Set the other fields * ====================================================== */ parallelLoop->setOpDatType (OP_DAT_ArgumentGroup, (opArgArguments->get_expressions ()[DAT_POSITION])->get_type ()); parallelLoop->setUniqueOpDat (globalName); parallelLoop->setOpDatVariableName (OP_DAT_ArgumentGroup, globalName); parallelLoop->setDuplicateOpDat (OP_DAT_ArgumentGroup, false); parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, GLOBAL); if ( opArgArguments->get_expressions ().size () == GBL_SCALAR_ARG_NUM ) setParallelLoopAccessDescriptor (parallelLoop, opArgArguments, OP_DAT_ArgumentGroup, GBL_SCALAR_ACC_POSITION); else setParallelLoopAccessDescriptor (parallelLoop, opArgArguments, OP_DAT_ArgumentGroup, GBL_ARRAY_ACC_POSITION); } else if ( functionName == "op_arg_dat_generic" ) { Debug::getInstance ()->debugMessage ("Found generic op_dat", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); /* * ====================================================== * Obtain the op_dat reference and its name * ====================================================== */ SgVarRefExp * opDatReference = NULL; opDatReference = getOpDatReferenceFromOpArg (opArgArguments); ROSE_ASSERT (opDatReference != NULL); string const opDatName = opDatReference->get_symbol ()->get_name ().getString (); /* * ====================================================== * Obtain the map reference and name, and select access * type (direct or indirect) * ====================================================== */ SgVarRefExp * opMapReference; opMapReference = getOpMapReferenceFromOpArg (opArgArguments); ROSE_ASSERT (opMapReference != NULL); string const mappingValue = opMapReference->get_symbol ()->get_name ().getString (); if (iequals (mappingValue, OP2::OP_ID)) { /* * ====================================================== * OP_ID signals identity mapping and therefore direct * access to the data * ====================================================== */ Debug::getInstance ()->debugMessage ("...DIRECT mapping descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, DIRECT); } else { Debug::getInstance ()->debugMessage ("...INDIRECT mapping descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpMapValue (OP_DAT_ArgumentGroup, INDIRECT); } /* * ====================================================== * In case of generic loop, I have to read also the * dimension and type to be able to set the op_dat info * in the parallel loop class * ====================================================== */ SgIntVal * opDatDimension = isSgIntVal ( opArgArguments->get_expressions ()[GENERIC_DIM_POSITION]); SgStringVal * opDataBaseTypeString = isSgStringVal ( opArgArguments->get_expressions ()[GENERIC_TYPE_POSITION]); ROSE_ASSERT (opDataBaseTypeString != NULL); SgType * opDataBaseType = getTypeFromString (opDataBaseTypeString->get_value (), opDatName); ROSE_ASSERT (opDataBaseType != NULL); setOpDatPropertiesGeneric (parallelLoop, opDatName, opDatDimension->get_value (), opDataBaseType, OP_DAT_ArgumentGroup); Debug::getInstance ()->debugMessage ("Getting access", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); setParallelLoopAccessDescriptor (parallelLoop, opArgArguments, OP_DAT_ArgumentGroup, GENERIC_ACC_POSITION); } else if ( functionName == "op_arg_mat" ) { Debug::getInstance ()->debugMessage ("Unsupported argument type", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); } else { Debug::getInstance ()->debugMessage ("Argument type not recognised", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); } /* * ====================================================== * This identifies the argument position in the data * structures, while the iteration variable 'i' identifies * the corresponding op_arg position in the op_par_loop * arguments (i == OP_DAT_ArgumentGroup + 2) * ====================================================== */ OP_DAT_ArgumentGroup++; } parallelLoop->setNumberOfOpDatArgumentGroups (numberOfOpArgs); parallelLoop->setNumberOfOpMatArgumentGroups (0); if ( parallelLoop->isDirectLoop () ) Debug::getInstance ()->debugMessage ("This is a DIRECT parallel loop", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); else Debug::getInstance ()->debugMessage ("This is an INDIRECT parallel loop", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); }
void FortranProgramDeclarationsAndDefinitions::setParallelLoopAccessDescriptor ( FortranParallelLoop * parallelLoop, SgExprListExp * actualArguments, unsigned int OP_DAT_ArgumentGroup, unsigned int accessPosition) { using boost::iequals; using boost::lexical_cast; using std::string; SgVarRefExp * accessExpression = isSgVarRefExp ( actualArguments->get_expressions ()[accessPosition]); string const accessValue = accessExpression->get_symbol ()->get_name ().getString (); if (iequals (accessValue, OP2::OP_READ)) { Debug::getInstance ()->debugMessage ("...READ access descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpAccessValue (OP_DAT_ArgumentGroup, READ_ACCESS); } else if (iequals (accessValue, OP2::OP_WRITE)) { Debug::getInstance ()->debugMessage ("...WRITE access descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpAccessValue (OP_DAT_ArgumentGroup, WRITE_ACCESS); } else if (iequals (accessValue, OP2::OP_INC)) { Debug::getInstance ()->debugMessage ("...INCREMENT access descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpAccessValue (OP_DAT_ArgumentGroup, INC_ACCESS); } else if (iequals (accessValue, OP2::OP_RW)) { Debug::getInstance ()->debugMessage ("...READ/WRITE access descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpAccessValue (OP_DAT_ArgumentGroup, RW_ACCESS); } else if (iequals (accessValue, OP2::OP_MAX)) { Debug::getInstance ()->debugMessage ("...MAXIMUM access descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpAccessValue (OP_DAT_ArgumentGroup, MAX_ACCESS); } else if (iequals (accessValue, OP2::OP_MIN)) { Debug::getInstance ()->debugMessage ("...MINIMUM access descriptor", Debug::OUTER_LOOP_LEVEL, __FILE__, __LINE__); parallelLoop->setOpAccessValue (OP_DAT_ArgumentGroup, MIN_ACCESS); } else { throw Exceptions::ParallelLoop::UnknownAccessException ( "Unknown access descriptor: '" + accessValue + "' for OP_DAT argument " + lexical_cast <string> (OP_DAT_ArgumentGroup)); } }
//! Execute random walk simulator application mode. void executeRandomWalkSimulator( const std::string databasePath, const tudat::input_output::parsed_data_vector_utilities::ParsedDataVectorPtr parsedData ) { /////////////////////////////////////////////////////////////////////////// // Declare using-statements. using std::advance; using std::cerr; using std::cout; using std::endl; using std::max_element; using std::min_element; using std::numeric_limits; using std::ofstream; using std::ostringstream; using std::setprecision; using std::string; using boost::iequals; using namespace boost::filesystem; using boost::make_shared; using namespace assist::astrodynamics; using namespace assist::basics; using namespace assist::mathematics; using namespace tudat::basic_astrodynamics::orbital_element_conversions; using namespace tudat::basic_mathematics::mathematical_constants; using namespace tudat::input_output; using namespace tudat::input_output::dictionary; using namespace tudat::statistics; using namespace stomi::astrodynamics; using namespace stomi::database; using namespace stomi::input_output; /////////////////////////////////////////////////////////////////////////// // Extract input parameters. // Get dictionary. const DictionaryPointer dictionary = getRandomWalkSimulatorDictionary( ); // Print database path to console. cout << "Database " << databasePath << endl; // Extract required parameters. const string randomWalkRunName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKRUN" ) ); cout << "Random walk run " << randomWalkRunName << endl; // Extract optional parameters. const int numberOfThreads = extractParameterValue< int >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "NUMBEROFTHREADS" ), 1 ); cout << "Number of threads " << numberOfThreads << endl; const string outputMode = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "OUTPUTMODE" ), "DATABASE" ); cout << "Output mode " << outputMode << endl; const string fileOutputDirectory = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "FILEOUTPUTDIRECTORY" ), "" ) + "/"; cout << "File output directory " << fileOutputDirectory << endl; const string randomWalkSimulations = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKSIMULATIONS" ), "ALL" ); cout << "Random walk simulations " << randomWalkSimulations << endl; const string randomWalkRunTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKRUNTABLENAME" ), "random_walk_run" ); cout << "Random walk run table " << randomWalkRunTableName << endl; const string randomWalkInputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKINPUTTABLENAME" ), "random_walk_input" ); cout << "Random walk input table " << randomWalkInputTableName << endl; const string randomWalkPerturberTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKPERTURBERTABLENAME" ), "random_walk_perturbers" ); cout << "Random walk perturber table " << randomWalkPerturberTableName << endl; const string randomWalkOutputTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "RANDOMWALKOUTPUTTABLENAME" ), "random_walk_output" ); cout << "Random walk output table " << randomWalkOutputTableName << endl; const string testParticleCaseTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLECASETABLENAME" ), "test_particle_case" ); cout << "Test particle case table " << testParticleCaseTableName << endl; const string testParticleKickTableName = extractParameterValue< string >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "TESTPARTICLEKICKTABLENAME" ), "test_particle_kicks" ); cout << "Test particle kick table " << testParticleKickTableName << endl; // Retrieve and store random walk run data from database. RandomWalkRunPointer randomWalkRun; // Random walk run data is extracted in local scope from the database, with overwritten // parameters extracted from the input file, to ensure that none of these parameters are used // globally elsewhere in this file. { const RandomWalkRunPointer retrievedRandomWalkRun = getRandomWalkRun( databasePath, randomWalkRunName, randomWalkRunTableName ); const double perturberRingNumberDensity = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "PERTURBERRINGNUMBERDENSITY" ), retrievedRandomWalkRun->perturberRingNumberDensity ); cout << "Perturber ring number density " << perturberRingNumberDensity << " perturbers per R_Hill" << endl; const double perturberRingMass = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "PERTURBERRINGMASS" ), retrievedRandomWalkRun->perturberRingMass ); cout << "Perturber ring mass " << perturberRingMass << " M_PerturbedBody" << endl; const double observationPeriod = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "OBSERVATIONPERIOD" ), retrievedRandomWalkRun->observationPeriod, &convertJulianYearsToSeconds ); cout << "Observation period " << convertSecondsToJulianYears( observationPeriod ) << " yrs" << endl; const unsigned int numberOfEpochWindows = extractParameterValue< unsigned int >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "NUMBEROFEPOCHWINDOWS" ), retrievedRandomWalkRun->numberOfEpochWindows ); cout << "Number of epoch windows " << numberOfEpochWindows << endl; const double epochWindowSize = extractParameterValue< double >( parsedData->begin( ), parsedData->end( ), findEntry( dictionary, "EPOCHWINDOWSIZE" ), retrievedRandomWalkRun->epochWindowSize, &convertJulianDaysToSeconds ); cout << "Epoch window size " << convertSecondsToJulianDays( epochWindowSize ) << " days" << endl; // Store random walk run data with possible overwritten data. randomWalkRun = make_shared< RandomWalkRun >( retrievedRandomWalkRun->randomWalkRunId, randomWalkRunName, retrievedRandomWalkRun->testParticleCaseId, perturberRingNumberDensity, perturberRingMass, observationPeriod, numberOfEpochWindows, epochWindowSize ); } // Check that all required parameters have been set. checkRequiredParameters( dictionary ); /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Fetch test particle case and random walk input data from database. cout << endl; cout << "****************************************************************************" << endl; cout << "Database operations" << endl; cout << "****************************************************************************" << endl; cout << endl; // Generate output message. cout << "Fetching test particle case data from database ..." << endl; // Retrieve and store test particle case data. const TestParticleCasePointer testParticleCaseData = getTestParticleCase( databasePath, randomWalkRun->testParticleCaseId, testParticleCaseTableName ); // Generate output message to indicate that test particle case data was fetched successfully. cout << "Test particle case data fetched successfully from database!" << endl; // Generate output message. cout << "Fetching random walk input data from database ..." << endl; // Check if all incomplete random walk simulations are to be executed and fetch the random // walk input table, else only fetch the requested random walk simulation IDs. RandomWalkInputTable randomWalkInputTable; if ( iequals( randomWalkSimulations, "ALL" ) ) { cout << "Fetching all incomplete random walk Monte Carlo runs ..." << endl; // Get entire random walk input table from database. randomWalkInputTable = getCompleteRandomWalkInputTable( databasePath, randomWalkRun->randomWalkRunId, randomWalkInputTableName, randomWalkPerturberTableName ); } else { cout << "Fetching all requested random walk Monte Carlo runs ..." << endl; // Get selected random walk input table from database. randomWalkInputTable = getSelectedRandomWalkInputTable( databasePath, randomWalkRun->randomWalkRunId, randomWalkSimulations, randomWalkInputTableName, randomWalkPerturberTableName ); } // Generate output message to indicate that the input table was fetched successfully. cout << "Random walk input data (" << randomWalkInputTable.size( ) << " rows) fetched successfully from database!" << endl; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute derived parameters. cout << endl; cout << "****************************************************************************" << endl; cout << "Derived parameters" << endl; cout << "****************************************************************************" << endl; cout << endl; // Compute epoch window spacing [s]. const double epochWindowSpacing = randomWalkRun->observationPeriod / ( randomWalkRun->numberOfEpochWindows - 1 ); cout << "Epoch window spacing " << convertSecondsToJulianDays( epochWindowSpacing ) << " days" << endl; // Compute mass of perturbed body [kg]. const double perturbedBodyMass = computeMassOfSphere( testParticleCaseData->perturbedBodyRadius, testParticleCaseData->perturbedBodyBulkDensity ); cout << "Perturbed body mass " << perturbedBodyMass << " kg" << endl; // Compute perturbed body's gravitational parameter [m^3 s^-2]. const double perturbedBodyGravitationalParameter = computeGravitationalParameter( perturbedBodyMass ); cout << "Perturbed body gravitational parameter " << perturbedBodyGravitationalParameter << " m^3 s^-2" << endl; // Compute perturber population using density and semi-major axis distribution limits. // Note, in the floor() function, adding 0.5 is a workaround for the fact that there is no // round() function in C++03 (it is available in C++11). ConvertHillRadiiToMeters convertHillRadiiToMeters( testParticleCaseData->centralBodyGravitationalParameter, perturbedBodyGravitationalParameter, testParticleCaseData->perturbedBodyStateInKeplerianElementsAtT0( semiMajorAxisIndex ) ); const double perturberRingNumberDensityInMeters = randomWalkRun->perturberRingNumberDensity / convertHillRadiiToMeters( 1.0 ); const unsigned int perturberPopulation = std::floor( 2.0 * testParticleCaseData->semiMajorAxisDistributionLimit * perturberRingNumberDensityInMeters + 0.5 ); cout << "Perturber population " << perturberPopulation << endl; // Compute perturber mass ratio. // Note, for the random walk simulations, the mass ratio is equal for all perturbers. const double perturberMassRatio = randomWalkRun->perturberRingMass / perturberPopulation; cout << "Perturber mass ratio " << perturberMassRatio << endl; /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Execute Monte Carlo simulation. cout << endl; cout << "****************************************************************************" << endl; cout << "Simulation loop" << endl; cout << "****************************************************************************" << endl; cout << endl; // Execute simulation loop. cout << "Starting simulation loop ... " << endl; cout << randomWalkInputTable.size( ) << " random walk simulations queued for execution ..." << endl; cout << endl; // Loop over input table. #pragma omp parallel for num_threads( numberOfThreads ) for ( unsigned int i = 0; i < randomWalkInputTable.size( ); i++ ) { /////////////////////////////////////////////////////////////////////////// // Set input table iterator and emit output message. // Set input table iterator for current simulation wrt to start of input table and counter. RandomWalkInputTable::iterator iteratorRandomWalkInputTable = randomWalkInputTable.begin( ); advance( iteratorRandomWalkInputTable, i ); // Emit output message. #pragma omp critical( outputToConsole ) { cout << "Random walk simulation " << iteratorRandomWalkInputTable->randomWalkSimulationId << " on thread " << omp_get_thread_num( ) + 1 << " / " << omp_get_num_threads( ) << endl; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Fetch test particle kick table based on test particle simulation IDs for random walk // simulation. TestParticleKickTable testParticleKickTable; #pragma omp critical( databaseOperations ) { testParticleKickTable = getTestParticleKickTable( databasePath, testParticleCaseData->randomWalkSimulationPeriod, iteratorRandomWalkInputTable->testParticleSimulationIds, testParticleKickTableName ); } // Check if output mode is set to "FILE". // If so, open output file and write test particle kick table data. // Check if the output directory exists: if not, create it. if ( iequals( outputMode, "FILE" ) ) { // Check if output directory exists. if ( !exists( fileOutputDirectory ) ) { cerr << "Directory does not exist. Will be created." << endl; create_directories( fileOutputDirectory ); } // Declare file handler. ofstream testParticleKickTableFile; // Set up and write file header to file. ostringstream testParticleKickTableFilename; testParticleKickTableFilename << fileOutputDirectory << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_testParticleKickTable.csv"; testParticleKickTableFile.open( testParticleKickTableFilename.str( ).c_str( ) ); testParticleKickTableFile << "kickId,simulationId,conjunctionEpoch,conjunctionDistance," << "preConjunctionEpoch,preConjunctionDistance," << "preConjunctionSemiMajorAxis,preConjunctionEccentricity," << "preConjunctionInclination,preConjunctionArgumentOfPeriapsis," << "preConjunctionLongitudeOfAscendingNode,preConjunctionTrueAnomaly" << "postConjunctionEpoch,postConjunctionDistance," << "postConjunctionSemiMajorAxis,postConjunctionEccentricity," << "postConjunctionInclination,postConjunctionArgumentOfPeriapsis," << "postConjunctionLongitudeOfAscendingNode,postConjunctionTrueAnomaly" << endl; testParticleKickTableFile << "# [-],[-],[s],[m],[s],[m],[m],[-],[rad],[rad],[rad],[rad]," << "[s],[m],[m],[-],[rad],[rad],[rad],[rad]" << endl; // Write test particle kick table to file. for ( TestParticleKickTable::iterator iteratorTestParticleKicks = testParticleKickTable.begin( ); iteratorTestParticleKicks != testParticleKickTable.end( ); iteratorTestParticleKicks++ ) { testParticleKickTableFile << iteratorTestParticleKicks->testParticleKickId << "," << iteratorTestParticleKicks->testParticleSimulationId << ","; testParticleKickTableFile << setprecision( numeric_limits< double >::digits10 ) << iteratorTestParticleKicks->conjunctionEpoch << "," << iteratorTestParticleKicks->conjunctionDistance << "," << iteratorTestParticleKicks->preConjunctionEpoch << "," << iteratorTestParticleKicks->preConjunctionDistance << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( semiMajorAxisIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( eccentricityIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( inclinationIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( argumentOfPeriapsisIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( longitudeOfAscendingNodeIndex ) << "," << iteratorTestParticleKicks->preConjunctionStateInKeplerianElements( trueAnomalyIndex ) << "," << iteratorTestParticleKicks->postConjunctionEpoch << "," << iteratorTestParticleKicks->postConjunctionDistance << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( semiMajorAxisIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( eccentricityIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( inclinationIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( argumentOfPeriapsisIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( longitudeOfAscendingNodeIndex ) << "," << iteratorTestParticleKicks->postConjunctionStateInKeplerianElements( trueAnomalyIndex ) << endl; } // Close file handler. testParticleKickTableFile.close( ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Execute random walk simulation. // Declare perturbed body propagation history. This stores the propagation history of the // action variables only (semi-major axis, eccentricity, inclination). DoubleKeyVector3dValueMap keplerianActionElementsHistory; // Set perturbed body initial state (actions) in Keplerian elements. keplerianActionElementsHistory[ 0.0 ] = testParticleCaseData->perturbedBodyStateInKeplerianElementsAtT0.segment( 0, 3 ); // Declare iterator to previous state in Keplerian elements. DoubleKeyVector3dValueMap::iterator iteratorPreviousKeplerianElements = keplerianActionElementsHistory.begin( ); // Loop through aggregate kick table and execute kicks on perturbed body. for ( TestParticleKickTable::iterator iteratorKickTable = testParticleKickTable.begin( ); iteratorKickTable != testParticleKickTable.end( ); iteratorKickTable++ ) { // Execute kick and store results in propagation history. keplerianActionElementsHistory[ iteratorKickTable->conjunctionEpoch ] = executeKick( iteratorPreviousKeplerianElements->second, iteratorKickTable, perturberMassRatio ); advance( iteratorPreviousKeplerianElements, 1 ); } // Check if output mode is set to "FILE". // If so, open output file and write header content. if ( iequals( outputMode, "FILE" ) ) { ostringstream keplerianActionElementsFilename; keplerianActionElementsFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_keplerianActionElements.csv"; ostringstream keplerianActionElementsFileHeader; keplerianActionElementsFileHeader << "epoch,semiMajorAxis,eccentricity,inclination" << endl; keplerianActionElementsFileHeader << "# [s],[m],[-],[rad]" << endl; writeDataMapToTextFile( keplerianActionElementsHistory, keplerianActionElementsFilename.str( ), fileOutputDirectory, keplerianActionElementsFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute average longitude residual and maximum longitude residual change in observation // period. // Declare average longitude residual in observation period [-]. double averageLongitudeResidual = TUDAT_NAN; // Declare maximum longitude residual change in observation period [-]. double maximumLongitudeResidualChange = TUDAT_NAN; // Declare map of average longitude residuals per window [rad]. DoubleKeyDoubleValueMap averageLongitudeResiduals; { // Populate temporary map with epochs and semi-major axes. DoubleKeyDoubleValueMap semiMajorAxisHistory; for ( DoubleKeyVector3dValueMap::iterator iteratorKeplerianActionElements = keplerianActionElementsHistory.begin( ); iteratorKeplerianActionElements != keplerianActionElementsHistory.end( ); iteratorKeplerianActionElements++ ) { semiMajorAxisHistory[ iteratorKeplerianActionElements->first ] = iteratorKeplerianActionElements->second( semiMajorAxisIndex ); } // Compute longitude history. DoubleKeyDoubleValueMap longitudeHistory = computeLongitudeHistory( semiMajorAxisHistory, testParticleCaseData->centralBodyGravitationalParameter ); // Compute reduced longitude history (data is reduced to only the epoch windows). DoubleKeyDoubleValueMap reducedLongitudeHistory = reduceLongitudeHistory( longitudeHistory, iteratorRandomWalkInputTable->observationPeriodStartEpoch, epochWindowSpacing, randomWalkRun->epochWindowSize, randomWalkRun->numberOfEpochWindows ); // Set input data for simple linear regression. SimpleLinearRegression longitudeHistoryRegression( reducedLongitudeHistory ); // Compute linear fit. longitudeHistoryRegression.computeFit( ); // Store longitude residuals history. DoubleKeyDoubleValueMap longitudeResidualsHistory; // Generate longitude history residuals by subtracting linear fit from data. for ( DoubleKeyDoubleValueMap::iterator iteratorReducedLongitudeHistory = reducedLongitudeHistory.begin( ); iteratorReducedLongitudeHistory != reducedLongitudeHistory.end( ); iteratorReducedLongitudeHistory++ ) { longitudeResidualsHistory[ iteratorReducedLongitudeHistory->first ] = iteratorReducedLongitudeHistory->second - longitudeHistoryRegression.getCoefficientOfConstantTerm( ) - longitudeHistoryRegression.getCoefficientOfLinearTerm( ) * iteratorReducedLongitudeHistory->first; } // Loop over observation period and compute average longitude residuals per epoch window. for ( int windowNumber = 0; windowNumber < randomWalkRun->numberOfEpochWindows; windowNumber++ ) { const double epochWindowCenter = iteratorRandomWalkInputTable->observationPeriodStartEpoch + windowNumber * epochWindowSpacing; averageLongitudeResiduals[ epochWindowCenter ] = computeStepFunctionWindowAverage( longitudeResidualsHistory, epochWindowCenter - 0.5 * randomWalkRun->epochWindowSize, epochWindowCenter + 0.5 * randomWalkRun->epochWindowSize ); } // Compute average longitude residual during propagation history. double sumLongitudeResiduals = 0.0; for ( DoubleKeyDoubleValueMap::iterator iteratorAverageLongitudeResiduals = averageLongitudeResiduals.begin( ); iteratorAverageLongitudeResiduals != averageLongitudeResiduals.end( ); iteratorAverageLongitudeResiduals++ ) { sumLongitudeResiduals += iteratorAverageLongitudeResiduals->second; } averageLongitudeResidual = sumLongitudeResiduals / randomWalkRun->numberOfEpochWindows; // Compute maximum longitude residual change during propagation history. maximumLongitudeResidualChange = ( max_element( averageLongitudeResiduals.begin( ), averageLongitudeResiduals.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second - ( min_element( averageLongitudeResiduals.begin( ), averageLongitudeResiduals.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second; // Check if output mode is set to "FILE". // If so, open output file and write header content. if ( iequals( outputMode, "FILE" ) ) { ostringstream longitudeHistoryFilename; longitudeHistoryFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_longitudeHistory.csv"; ostringstream longitudeHistoryFileHeader; longitudeHistoryFileHeader << "epoch,longitude" << endl; longitudeHistoryFileHeader << "# [s],[rad]" << endl; writeDataMapToTextFile( longitudeHistory, longitudeHistoryFilename.str( ), fileOutputDirectory, longitudeHistoryFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); ostringstream reducedLongitudeHistoryFilename; reducedLongitudeHistoryFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_reducedLongitudeHistory.csv"; ostringstream reducedLongitudeHistoryFileHeader; reducedLongitudeHistoryFileHeader << "epoch,longitude" << endl; reducedLongitudeHistoryFileHeader << "# [s],[rad]" << endl; writeDataMapToTextFile( reducedLongitudeHistory, reducedLongitudeHistoryFilename.str( ), fileOutputDirectory, reducedLongitudeHistoryFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); ostringstream longitudeResidualsFilename; longitudeResidualsFilename << "randomWalkSimulation" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_longitudeResiduals.csv"; ostringstream longitudeResidualsFileHeader; longitudeResidualsFileHeader << "epoch,longitudeResidual" << endl; longitudeResidualsFileHeader << "# [s],[rad]" << endl; writeDataMapToTextFile( longitudeResidualsHistory, longitudeResidualsFilename.str( ), fileOutputDirectory, longitudeResidualsFileHeader.str( ), numeric_limits< double >::digits10, numeric_limits< double >::digits10, "," ); } } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute average eccentricity and maximum eccentricity change in observation window. // Declare average eccentricity in observation period [-]. double averageEccentricity = TUDAT_NAN; // Declare maximum eccentricity change in observation period [-]. double maximumEccentricityChange = TUDAT_NAN; // Declare map of average eccentricities per window [-]. DoubleKeyDoubleValueMap averageEccentricities; { // Populate temporary map with epochs and eccentricities. DoubleKeyDoubleValueMap eccentricityHistory; for ( DoubleKeyVector3dValueMap::iterator iteratorKeplerianActionElements = keplerianActionElementsHistory.begin( ); iteratorKeplerianActionElements != keplerianActionElementsHistory.end( ); iteratorKeplerianActionElements++ ) { eccentricityHistory[ iteratorKeplerianActionElements->first ] = iteratorKeplerianActionElements->second( eccentricityIndex ); } // Loop over observation period and compute average eccentricities per epoch window. for ( int windowNumber = 0; windowNumber < randomWalkRun->numberOfEpochWindows; windowNumber++ ) { const double epochWindowCenter = iteratorRandomWalkInputTable->observationPeriodStartEpoch + windowNumber * epochWindowSpacing; averageEccentricities[ epochWindowCenter ] = computeStepFunctionWindowAverage( eccentricityHistory, epochWindowCenter - 0.5 * randomWalkRun->epochWindowSize, epochWindowCenter + 0.5 * randomWalkRun->epochWindowSize ); } // Compute average eccentricity during propagation history. double sumEccentricities = 0.0; for ( DoubleKeyDoubleValueMap::iterator iteratorAverageEccentricities = averageEccentricities.begin( ); iteratorAverageEccentricities != averageEccentricities.end( ); iteratorAverageEccentricities++ ) { sumEccentricities += iteratorAverageEccentricities->second; } averageEccentricity = sumEccentricities / randomWalkRun->numberOfEpochWindows; // Compute maximum eccentricity change during propagation history. maximumEccentricityChange = ( max_element( averageEccentricities.begin( ), averageEccentricities.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second - ( min_element( averageEccentricities.begin( ), averageEccentricities.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Compute average inclination and maximum inclination change in observation window. // Declare average inclination in observation period [rad]. double averageInclination = TUDAT_NAN; // Declare maximum inclination change in observation period [rad]. double maximumInclinationChange = TUDAT_NAN; // Declare map of average inclinations per window [rad]. DoubleKeyDoubleValueMap averageInclinations; { // Populate temporary map with epochs and inclinations. DoubleKeyDoubleValueMap inclinationHistory; for ( DoubleKeyVector3dValueMap::iterator iteratorKeplerianActionElements = keplerianActionElementsHistory.begin( ); iteratorKeplerianActionElements != keplerianActionElementsHistory.end( ); iteratorKeplerianActionElements++ ) { inclinationHistory[ iteratorKeplerianActionElements->first ] = iteratorKeplerianActionElements->second( inclinationIndex ); } // Loop over observation period and compute average inclinations per epoch window. for ( int windowNumber = 0; windowNumber < randomWalkRun->numberOfEpochWindows; windowNumber++ ) { const double epochWindowCenter = iteratorRandomWalkInputTable->observationPeriodStartEpoch + windowNumber * epochWindowSpacing; averageInclinations[ epochWindowCenter ] = computeStepFunctionWindowAverage( inclinationHistory, epochWindowCenter - randomWalkRun->epochWindowSize * 0.5, epochWindowCenter + randomWalkRun->epochWindowSize * 0.5 ); } // Compute average inclination during propagation history. double sumInclinations = 0.0; for ( DoubleKeyDoubleValueMap::iterator iteratorAverageInclinations = averageInclinations.begin( ); iteratorAverageInclinations != averageInclinations.end( ); iteratorAverageInclinations++ ) { sumInclinations += iteratorAverageInclinations->second; } averageInclination = sumInclinations / randomWalkRun->numberOfEpochWindows; // Compute maximum inclination change during propagation history. maximumInclinationChange = ( max_element( averageInclinations.begin( ), averageInclinations.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second - ( min_element( averageInclinations.begin( ), averageInclinations.end( ), CompareDoubleKeyDoubleValueMapValues( ) ) )->second; } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Write epoch-windoow average values to file. // Check if output mode is set to "FILE". // If so, open output file and write header content. if ( iequals( outputMode, "FILE" ) ) { // Declare file handler. ofstream epochWindowAveragesFile; ostringstream epochWindowAveragesFilename; epochWindowAveragesFilename << fileOutputDirectory << "randomWalkRun" << iteratorRandomWalkInputTable->randomWalkSimulationId << "_epochWindowAverages.csv"; epochWindowAveragesFile.open( epochWindowAveragesFilename.str( ).c_str( ) ); epochWindowAveragesFile << "epoch,longitudeResidual,eccentricity,inclination" << endl; epochWindowAveragesFile << "# [s],[rad],[-],[rad]" << endl; // Loop through epoch-window averages and write data to file. DoubleKeyDoubleValueMap::iterator iteratorEpochWindowAverageLongitudeResiduals = averageLongitudeResiduals.begin( ); DoubleKeyDoubleValueMap::iterator iteratorEpochWindowAverageEccentricities = averageEccentricities.begin( ); DoubleKeyDoubleValueMap::iterator iteratorEpochWindowAverageInclinations = averageInclinations.begin( ); for ( int i = 0; i < randomWalkRun->numberOfEpochWindows; i++ ) { epochWindowAveragesFile << setprecision( numeric_limits< double >::digits10 ) << iteratorEpochWindowAverageLongitudeResiduals->first << "," << iteratorEpochWindowAverageLongitudeResiduals->second << "," << iteratorEpochWindowAverageEccentricities->second << "," << iteratorEpochWindowAverageInclinations->second << endl; iteratorEpochWindowAverageLongitudeResiduals++; iteratorEpochWindowAverageEccentricities++; iteratorEpochWindowAverageInclinations++; } // Close file handler. epochWindowAveragesFile.close( ); } /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Write random walk output to database. To avoid locking of the database, this section is // thread-critical, so will be executed one-by-one by multiple threads. // Check if output mode is set to "DATABASE". if ( iequals( outputMode, "DATABASE" ) ) { #pragma omp critical( databaseOperations ) { // Populate output table in database. populateRandomWalkOutputTable( databasePath, iteratorRandomWalkInputTable->randomWalkSimulationId, averageLongitudeResidual, maximumLongitudeResidualChange, averageEccentricity, maximumEccentricityChange, averageInclination, maximumInclinationChange, randomWalkOutputTableName, randomWalkInputTableName ); } } ///////////////////////////////////////////////////////////////// } // simulation for-loop /////////////////////////////////////////////////////////////////// }