// Generator for toplevel expression // It also evaluates the generated function llvm::Function * ProgCodegen::operator()(const ast::Expr & expr) const { std::vector<llvm::Type*> doubles(0,llvm::Type::getDoubleTy(llvm::getGlobalContext())); llvm::FunctionType * FT = llvm::FunctionType::get (llvm::Type::getDoubleTy(llvm::getGlobalContext()),llvm::ArrayRef<llvm::Type*>(doubles), false); llvm::Function * funcVal = llvm::Function ::Create(FT, llvm::Function::ExternalLinkage,"", module); if (funcVal == 0) return 0; //Creating ExprCodegen to process the function body. ExprCodegen expCG(module); //Building llvm::BasicBlock * BB = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", funcVal); expCG.pimpl->builder.SetInsertPoint(BB); if(llvm::Value * bodyVal = boost::apply_visitor(expCG,expr)) { expCG.pimpl->builder.CreateRet(bodyVal); llvm::verifyFunction(*funcVal); //Evaluation std::cout << "ready " << engine << "\n"; void *FPtr = engine->getPointerToFunction(funcVal); double (*FP)() = (double (*)())FPtr; std::cout << "Evaluated to " << FP() << "\n"; return funcVal; } funcVal->eraseFromParent(); return 0; }
// ============================================================================ StatusCode Tuples::TupleObj::column ( const std::string& name , const double value ) { if ( invalid() ) { return InvalidTuple ; } Double * item = doubles ( name ) ; if ( !item ) { return InvalidColumn ; } *item = value ; return StatusCode::SUCCESS ; }
/* This test *may* deadlock if we don't use non-blocking communication */ void TestNonBlockingSendingClass() throw (Exception) { ObjectCommunicator<ClassOfSimpleVariables> communicator; { // Create a simple class to send std::vector<double> doubles(3); doubles[0] = 1.1; doubles[1] = 1.2; doubles[2] = 1.3 + PetscTools::GetMyRank(); std::vector<bool> bools(2); bools[0] = true; bools[1] = true; boost::shared_ptr<ClassOfSimpleVariables> p_new_class(new ClassOfSimpleVariables(42,"hello",doubles,bools)); // Send the class for (unsigned p=0; p < PetscTools::GetNumProcs(); p++) { if (p != PetscTools::GetMyRank()) { p_new_class->mVectorOfDoubles[1] = 1.2 + p; // Arguments are object, destination, tag communicator.ISendObject(p_new_class, p, 123 + PetscTools::GetMyRank()); } } } { boost::shared_ptr<ClassOfSimpleVariables> p_recv_class; for (unsigned p=0; p < PetscTools::GetNumProcs(); p++) { if (p != PetscTools::GetMyRank()) { communicator.IRecvObject(p, 123 + p); p_recv_class = communicator.GetRecvObject(); // Check that the values are correct TS_ASSERT_EQUALS(p_recv_class->GetNumber(),42); TS_ASSERT_EQUALS(p_recv_class->GetString(),"hello"); TS_ASSERT_EQUALS(p_recv_class->GetVectorOfDoubles().size(),3u); TS_ASSERT_EQUALS(p_recv_class->GetVectorOfBools().size(),2u); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[0],1.1,1e-12); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[1],1.2 + PetscTools::GetMyRank(),1e-12); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[2],1.3 + p,1e-12); TS_ASSERT(p_recv_class->GetVectorOfBools()[0]); TS_ASSERT(p_recv_class->GetVectorOfBools()[1]); } } } PetscTools::Barrier("Make sure that no ISendObject buffers are in use before proceeding"); }
/** We cannot pre-post Irecv because we need to know the (dynamic) size of the object being sent first */ void TestNonBlockingRecvClass() throw (Exception) { ObjectCommunicator<ClassOfSimpleVariables> communicator; if (PetscTools::AmMaster()) { // Create a simple class to send std::vector<double> doubles(3); doubles[0] = 1.1; doubles[1] = 1.2; doubles[2] = 1.3; std::vector<bool> bools(2); bools[0] = true; bools[1] = true; boost::shared_ptr<ClassOfSimpleVariables> p_new_class(new ClassOfSimpleVariables(42,"hello",doubles,bools)); // Send the class for (unsigned p=1; p < PetscTools::GetNumProcs(); p++) { // Arguments are object, destination, tag p_new_class->mVectorOfDoubles[1] = 1.2 + p; communicator.ISendObject(p_new_class, p, 123); } } else { boost::shared_ptr<ClassOfSimpleVariables> p_recv_class; TS_ASSERT_THROWS_THIS(p_recv_class = communicator.GetRecvObject(), "No object to receive in ObjectCommunicator::GetRecvObject"); // Receive the string. This returns before the receive is complete. communicator.IRecvObject(0, 123); // Get an object from the communicator. Implicit MPI_Wait. p_recv_class = communicator.GetRecvObject(); // Check that the values are correct TS_ASSERT_EQUALS(p_recv_class->GetNumber(),42); TS_ASSERT_EQUALS(p_recv_class->GetString(),"hello"); TS_ASSERT_EQUALS(p_recv_class->GetVectorOfDoubles().size(),3u); TS_ASSERT_EQUALS(p_recv_class->GetVectorOfBools().size(),2u); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[0],1.1,1e-12); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[1],1.2+PetscTools::GetMyRank(),1e-12); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[2],1.3,1e-12); TS_ASSERT(p_recv_class->GetVectorOfBools()[0]); TS_ASSERT(p_recv_class->GetVectorOfBools()[1]); } PetscTools::Barrier("Make sure that no ISendObject buffers are in use before proceeding"); }
llvm::Function* PrototypeAST::codegen() { debug_info_helper->emitLocation(getLoc()); std::vector<llvm::Type*> doubles(args_.size(), llvm::Type::getDoubleTy(*context)); llvm::FunctionType* function_type = llvm::FunctionType::get(llvm::Type::getDoubleTy(*context), doubles, false); llvm::Function* function = llvm::Function::Create(function_type, llvm::GlobalValue::ExternalLinkage, name_, cur_module); auto arg_it = function->arg_begin(); for (size_t i = 0; i < function->arg_size(); ++i, ++arg_it) { arg_it->setName(args_[i]); } return function; }
void TestSendingClass() throw (Exception) { MPI_Status status; ObjectCommunicator<ClassOfSimpleVariables> communicator; if (PetscTools::AmMaster()) { // Create a simple class to send std::vector<double> doubles(3); doubles[0] = 1.1; doubles[1] = 1.2; doubles[2] = 1.3; std::vector<bool> bools(2); bools[0] = true; bools[1] = true; boost::shared_ptr<ClassOfSimpleVariables> p_new_class(new ClassOfSimpleVariables(42,"hello",doubles,bools)); // Send the class for (unsigned p=1; p < PetscTools::GetNumProcs(); p++) { // Arguments are object, destination, tag communicator.SendObject(p_new_class, p, 123); } } else { boost::shared_ptr<ClassOfSimpleVariables> p_recv_class; p_recv_class = communicator.RecvObject(0, 123, status); // Check that the values are correct TS_ASSERT_EQUALS(p_recv_class->GetNumber(),42); TS_ASSERT_EQUALS(p_recv_class->GetString(),"hello"); TS_ASSERT_EQUALS(p_recv_class->GetVectorOfDoubles().size(),3u); TS_ASSERT_EQUALS(p_recv_class->GetVectorOfBools().size(),2u); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[0],1.1,1e-12); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[1],1.2,1e-12); TS_ASSERT_DELTA(p_recv_class->GetVectorOfDoubles()[2],1.3,1e-12); TS_ASSERT(p_recv_class->GetVectorOfBools()[0]); TS_ASSERT(p_recv_class->GetVectorOfBools()[1]); } }
// Prototype (declaration) generator llvm::Function * ProgCodegen::operator()(const ast::Prototype & proto) const { std::vector<llvm::Type*> doubles(proto.args.size(),llvm::Type::getDoubleTy(llvm::getGlobalContext())); llvm::FunctionType * FT = llvm::FunctionType::get (llvm::Type::getDoubleTy(llvm::getGlobalContext()), llvm::ArrayRef<llvm::Type*>(doubles), false); llvm::Function * F = llvm::Function ::Create(FT, llvm::Function::ExternalLinkage, proto.name, module); // No redefinitions or redeclarations if(F->getName() != proto.name) { F->eraseFromParent(); F = module->getFunction(proto.name); if(!F->empty()) return FCgError("redefinition of a function", proto.name); if(F->arg_size() != proto.args.size()) return FCgError("redefinition of a function with different # args",proto.name); } return F; }
void TestSendRecv() throw (Exception) { if (PetscTools::GetNumProcs() == 2) { MPI_Status status; ObjectCommunicator<ClassOfSimpleVariables> communicator; // Create a simple class to send std::vector<double> doubles(3); doubles[0] = 1.1; doubles[1] = 1.2; doubles[2] = 1.3; std::vector<bool> bools(2); bools[0] = true; bools[1] = true; boost::shared_ptr<ClassOfSimpleVariables> p_send_class(new ClassOfSimpleVariables(42,"hello",doubles,bools)); boost::shared_ptr<ClassOfSimpleVariables> p_class(new ClassOfSimpleVariables); // Arguments are object, destination, tag p_class = communicator.SendRecvObject(p_send_class, 1-PetscTools::GetMyRank(), 123, 1-PetscTools::GetMyRank(), 123, status); // Check that the values are correct TS_ASSERT_EQUALS(p_class->GetNumber(),42); TS_ASSERT_EQUALS(p_class->GetString(),"hello"); TS_ASSERT_EQUALS(p_class->GetVectorOfDoubles().size(),3u); TS_ASSERT_EQUALS(p_class->GetVectorOfBools().size(),2u); TS_ASSERT_DELTA(p_class->GetVectorOfDoubles()[0],1.1,1e-12); TS_ASSERT_DELTA(p_class->GetVectorOfDoubles()[1],1.2,1e-12); TS_ASSERT_DELTA(p_class->GetVectorOfDoubles()[2],1.3,1e-12); TS_ASSERT(p_class->GetVectorOfBools()[0]); TS_ASSERT(p_class->GetVectorOfBools()[1]); } }
int main(){ char name[20] ; scanf("%19[0-9a-zA-Z -]s", name); name[0] = toupper(name[0]); doubles( name ) ; }
bool HamPathVisitor::permutateAndValidate() { _coloredEdges.clear(); _edgeColors.clear(); const vector<Node*>& nodes = _graph->getNodes(); // keep on permutating until we get one without doubles do { _positions[_positions.size()-1]++; for ( unsigned i = _positions.size()-1; i > 0; i-- ) { // overflowing, reset last position if (_positions[i] >= static_cast<int>(_positions.size())) { int dif = _positions[i] - (_positions.size() -1); _positions[i-1] += dif; _positions[i] = 0; // start value } } // reached the end, graph has no hamiltonian path if (_positions[0] >= static_cast<int>(_positions.size())) { _finished = true; // reset the color vector<Node*> nodes = _graph->getNodes(); for (unsigned i = 0; i < nodes.size(); ++i) nodes[i]->setColor(_nodeColors[i]); for (unsigned i = 0; i < _coloredEdges.size(); ++i) _coloredEdges[i]->setColor(_edgeColors[i]); throw InvalidGraph("The graph does not contain an Hamiltonian path.", 1); } // set the new permutation and set it's color to orange because it's a candidate path for (unsigned i = 0; i < _positions.size(); ++i) { _permutation[i] = nodes[_positions[i]]; _permutation[i]->setColor(RGB::colorOrange()); } } while (doubles(_positions) ); // passed to isEdge Edge* edge; unsigned size = nodes.size(); // check if the permutation is a hamiltonian path // verification stage for (unsigned i = 0; i < size - 1; ++i) { // if (_path[i], _path[i+1]) is not an edge if ( !isEdge(_permutation[i], _permutation[i+1], &edge) ) return false; // if there is an edge, color it else { _drew = true; _edgeColors.push_back(edge->getColor()); edge->setColor(RGB::colorOrange()); _coloredEdges.push_back(edge); } } // if we get here, it was a hamiltonian path! return true; }