virtual std::string generateIndexedIndependent(const OperationNode<Base>& indexedIndep, const IndexPattern& ip) override { bool isX = indexedIndep.getInfo()[0] == 0; if (isX) { return _nameGen->generateIndexedIndependent(indexedIndep, ip); } size_t nIndex = indexedIndep.getArguments().size(); CPPADCG_ASSERT_KNOWN(indexedIndep.getOperationType() == CGOpCode::LoopIndexedIndep, "Invalid node type"); CPPADCG_ASSERT_KNOWN(nIndex > 0, "Invalid number of arguments"); std::vector<const IndexDclrOperationNode<Base>*> indices(nIndex); for (size_t i = 0; i < nIndex; ++i) {// typically there is only one index but there may be more CPPADCG_ASSERT_KNOWN(indexedIndep.getArguments()[i].getOperation() != nullptr, "Invalid argument"); CPPADCG_ASSERT_KNOWN(indexedIndep.getArguments()[i].getOperation()->getOperationType() == CGOpCode::Index, "Invalid argument"); indices[i] = &static_cast<const IndexOperationNode<Base>&> (*indexedIndep.getArguments()[i].getOperation()).getIndex(); } _ss.clear(); _ss.str(""); _ss << _multName << "[" << LanguageC<Base>::indexPattern2String(ip, indices) << "]"; return _ss.str(); }
inline const IndexDclrOperationNode<Base>& getIndex() const { const std::vector<Argument<Base> >& args = this->getArguments(); CPPADCG_ASSERT_KNOWN(!args.empty(), "Invalid number of arguments"); OperationNode<Base>* aNode = args[0].getOperation(); CPPADCG_ASSERT_KNOWN(aNode != nullptr && aNode->getOperationType() == CGOpCode::IndexDeclaration, "Invalid argument operation type"); return static_cast<const IndexDclrOperationNode<Base>&> (*aNode); }
LangCDefaultHessianVarNameGenerator(VariableNameGenerator<Base>* nameGen, const std::string& multName, size_t n) : _nameGen(nameGen), _minMultiplierID(n + 1), _multName(multName) { CPPADCG_ASSERT_KNOWN(_nameGen != nullptr, "The name generator must not be null"); CPPADCG_ASSERT_KNOWN(_multName.size() > 0, "The name for the multipliers must not be empty"); initialize(); }
inline ModelLibraryCSourceGen(ModelCSourceGen<Base>& headModel, Ms&... rest) : ModelLibraryCSourceGen(rest...) { CPPADCG_ASSERT_KNOWN(_models.find(headModel.getName()) == _models.end(), "Another model with the same name was already registered"); _models[headModel.getName()] = &headModel; }
/** * Creates a new helper class for the generation of dynamic libraries * using the C language. * * @param model A model compilation helper (must only be deleted after * this object) */ inline ModelLibraryCSourceGen(ModelCSourceGen<Base>& model): _multiThreading(MultiThreadingType::NONE) { CPPADCG_ASSERT_KNOWN(_models.find(model.getName()) == _models.end(), "Another model with the same name was already registered"); _models[model.getName()] = &model; // must not use initializer_list constructor of map! }
/** * Adds additional models to be compiled into the created library. * * @param model a model compilation helper (must only be deleted after * this object) */ inline void addModel(ModelCSourceGen<Base>& model) { CPPADCG_ASSERT_KNOWN(_models.find(model.getName()) == _models.end(), "Another model with the same name was already registered"); _models[model.getName()] = &model; _libSources.clear(); // must regenerate library sources again }
LangCDefaultHessianVarNameGenerator(VariableNameGenerator<Base>* nameGen, size_t n) : _nameGen(nameGen), _minMultiplierID(n + 1), _multName("mult") { CPPADCG_ASSERT_KNOWN(_nameGen != nullptr, "The name generator must not be NULL"); initialize(); }
LinuxDynamicLib(const std::string& dynLibName) : _dynLibName(dynLibName), _dynLibHandle(nullptr) { std::string path; if (dynLibName[0] == '/') { path = dynLibName; // absolute path } else if (!(dynLibName[0] == '.' && dynLibName[1] == '/') && !(dynLibName[0] == '.' && dynLibName[1] == '.')) { path = "./" + dynLibName; // relative path } else { path = dynLibName; } // load the dynamic library _dynLibHandle = dlopen(path.c_str(), RTLD_NOW); CPPADCG_ASSERT_KNOWN(_dynLibHandle != nullptr, ("Failed to dynamically load library '" + dynLibName + "': " + dlerror()).c_str()); // validate the dynamic library validate(); }
inline std::string LanguageC<Base>::indexPattern2String(const IndexPattern& ip, const std::vector<const IndexDclrOperationNode<Base>*>& indexes) { std::stringstream ss; switch (ip.getType()) { case IndexPatternType::Linear: // y = x * a + b { CPPADCG_ASSERT_KNOWN(indexes.size() == 1, "Invalid number of indexes"); const LinearIndexPattern& lip = static_cast<const LinearIndexPattern&> (ip); return linearIndexPattern2String(lip, *indexes[0]); } case IndexPatternType::Sectioned: { CPPADCG_ASSERT_KNOWN(indexes.size() == 1, "Invalid number of indexes"); const SectionedIndexPattern* lip = static_cast<const SectionedIndexPattern*> (&ip); const std::map<size_t, IndexPattern*>& sections = lip->getLinearSections(); size_t sSize = sections.size(); CPPADCG_ASSERT_UNKNOWN(sSize > 1); std::map<size_t, IndexPattern*>::const_iterator its = sections.begin(); for (size_t s = 0; s < sSize - 1; s++) { const IndexPattern* lp = its->second; ++its; size_t xStart = its->first; ss << "(" << (*indexes[0]->getName()) << "<" << xStart << ")? " << indexPattern2String(*lp, *indexes[0]) << ": "; } ss << indexPattern2String(*its->second, *indexes[0]); return ss.str(); } case IndexPatternType::Plane2D: // y = f(x) + f(z) { CPPADCG_ASSERT_KNOWN(indexes.size() >= 1, "Invalid number of indexes"); std::string indexExpr; const Plane2DIndexPattern& pip = static_cast<const Plane2DIndexPattern&> (ip); bool useParens = pip.getPattern1() != nullptr && pip.getPattern2() != nullptr; if (useParens) indexExpr += "("; if (pip.getPattern1() != nullptr) indexExpr += indexPattern2String(*pip.getPattern1(), *indexes[0]); if (useParens) indexExpr += ") + ("; if (pip.getPattern2() != nullptr) indexExpr += indexPattern2String(*pip.getPattern2(), *indexes.back()); if (useParens) indexExpr += ")"; return indexExpr; } case IndexPatternType::Random1D: { CPPADCG_ASSERT_KNOWN(indexes.size() == 1, "Invalid number of indexes"); const Random1DIndexPattern& rip = static_cast<const Random1DIndexPattern&> (ip); CPPADCG_ASSERT_KNOWN(!rip.getName().empty(), "Invalid name for array"); return rip.getName() + "[" + (*indexes[0]->getName()) + "]"; } case IndexPatternType::Random2D: { CPPADCG_ASSERT_KNOWN(indexes.size() == 2, "Invalid number of indexes"); const Random2DIndexPattern& rip = static_cast<const Random2DIndexPattern&> (ip); CPPADCG_ASSERT_KNOWN(!rip.getName().empty(), "Invalid name for array"); return rip.getName() + "[" + (*indexes[0]->getName()) + "][" + (*indexes[1]->getName()) + "]"; } default: CPPADCG_ASSERT_UNKNOWN(false); // should never reach this return ""; } }
inline IndexDclrOperationNode(const std::string& name) : OperationNode<Base>(CGOpCode::IndexDeclaration) { CPPADCG_ASSERT_KNOWN(!name.empty(), "index name cannot be empty"); this->setName(name); }
inline OperationNode<Base>& getIndexCreationNode() const { const std::vector<Argument<Base> >& args = this->getArguments(); CPPADCG_ASSERT_KNOWN(!args.empty(), "Invalid number of arguments"); CPPADCG_ASSERT_KNOWN(args.back().getOperation() != nullptr, "Invalid argument type"); return *args.back().getOperation(); }
inline void setLibraryName(const std::string& libraryName) { CPPADCG_ASSERT_KNOWN(!libraryName.empty(), "Library name cannot be empty"); _libraryName = libraryName; }
void addCustomFunctionSource(const std::string& filename, const std::string& source) { CPPADCG_ASSERT_KNOWN(!filename.empty(), "The filename name cannot be empty"); _customSource[filename] = source; }