Example #1
0
std::unique_ptr<std::vector<CFileEntry>>
CSelectWithMatching::select_out(std::unique_ptr<std::vector<CFileEntry>> data){

    //select only those files which hash equal on of those in the matching vector
    std::unique_ptr<std::vector<CFileEntry>> merged_endresult(new std::vector<CFileEntry>);

    std::for_each(m_matching->begin(),
                  m_matching->end(),
                  [&data, &merged_endresult](CFileEntry& elem){

        elem.createHash();

        auto range = std::equal_range(data->begin(),
                                      data->end(),
                                      elem);

        if(range.first != data->end()){
            std::copy(range.first,
                      range.second,
                      std::back_inserter(*merged_endresult));
        }

    });

    return std::move(merged_endresult);
}
Example #2
0
void JuliaOJIT::addModule(std::unique_ptr<Module> M)
{
#ifndef JL_NDEBUG
    // validate the relocations for M
    for (Module::iterator I = M->begin(), E = M->end(); I != E; ) {
        Function *F = &*I;
        ++I;
        if (F->isDeclaration()) {
            if (F->use_empty())
                F->eraseFromParent();
            else if (!(isIntrinsicFunction(F) ||
                       findUnmangledSymbol(F->getName()) ||
                       SectionMemoryManager::getSymbolAddressInProcess(
                           getMangledName(F->getName())))) {
                std::cerr << "FATAL ERROR: "
                          << "Symbol \"" << F->getName().str() << "\""
                          << "not found";
                abort();
            }
        }
    }
#endif
    JL_TIMING(LLVM_MODULE_FINISH);
    // We need a memory manager to allocate memory and resolve symbols for this
    // new module. Create one that resolves symbols by looking back into the JIT.
    auto Resolver = orc::createLambdaResolver(
                      [&](const std::string &Name) {
                        // TODO: consider moving the FunctionMover resolver here
                        // Step 0: ObjectLinkingLayer has checked whether it is in the current module
                        // Step 1: See if it's something known to the ExecutionEngine
                        if (auto Sym = findSymbol(Name, true)) {
#if JL_LLVM_VERSION >= 40000
                            // `findSymbol` already eagerly resolved the address
                            // return it directly.
                            return Sym;
#else
                            return RuntimeDyld::SymbolInfo(Sym.getAddress(),
                                                           Sym.getFlags());
#endif
                        }
                        // Step 2: Search the program symbols
                        if (uint64_t addr = SectionMemoryManager::getSymbolAddressInProcess(Name))
                            return JL_SymbolInfo(addr, JITSymbolFlags::Exported);
#if defined(_OS_LINUX_)
                        if (uint64_t addr = resolve_atomic(Name.c_str()))
                            return JL_SymbolInfo(addr, JITSymbolFlags::Exported);
#endif
                        // Return failure code
                        return JL_SymbolInfo(nullptr);
                      },
                      [](const std::string &S) { return nullptr; }
                    );
    SmallVector<std::unique_ptr<Module>,1> Ms;
    Ms.push_back(std::move(M));
    auto modset = CompileLayer.addModuleSet(std::move(Ms), MemMgr,
                                            std::move(Resolver));
    // Force LLVM to emit the module so that we can register the symbols
    // in our lookup table.
    CompileLayer.emitAndFinalize(modset);
}
EdgeBasedGraphFactory::EdgeBasedGraphFactory(std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
                                   std::shared_ptr<RestrictionMap> restriction_map,
                                   std::unique_ptr<std::vector<NodeID>> barrier_node_list,
                                   std::unique_ptr<std::vector<NodeID>> traffic_light_node_list,
                                   const std::vector<QueryNode> &node_info_list,
                                   const SpeedProfileProperties &speed_profile)
    : speed_profile(speed_profile),
      m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
      m_node_info_list(node_info_list),
      m_node_based_graph(std::move(node_based_graph)),
      m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0)
{
    // insert into unordered sets for fast lookup
    m_barrier_nodes.insert(barrier_node_list->begin(), barrier_node_list->end());
    m_traffic_lights.insert(traffic_light_node_list->begin(), traffic_light_node_list->end());
}
	///<summary>
	/// コンストラクタ
	/// UNIX_TIMESTAMPの系列を渡して経過時刻のリストに変換する
	/// relative_to_firstをfalseにすると生のUNIX_TIMESTAMPの値をそのまま保持する
	///</summary>
	TimeSlotManager::TimeSlotManager(std::unique_ptr<std::vector<time_t>> timeslots, bool relative_to_first)
	{
		std::sort(timeslots->begin(), timeslots->end());
		if (!relative_to_first) this->timeslots = std::move(timeslots);
		else {
			this->timeslots = std::make_unique<std::vector<time_t>>(timeslots->size());
			if (timeslots->size() == 0) return;

			time_t first = timeslots->at(0);
			for (int i = 0; i < timeslots->size(); i++) {
				this->timeslots->at(i) = timeslots->at(i) - first;
			}
		}
	}
Example #5
0
    ModuleHandleT addModule(std::unique_ptr<Module> M)
    {
#ifndef NDEBUG
        // validate the relocations for M
        for (Module::iterator I = M->begin(), E = M->end(); I != E; ) {
            Function *F = &*I;
            ++I;
            if (F->isDeclaration()) {
                if (F->use_empty())
                    F->eraseFromParent();
                else
                    assert(F->isIntrinsic() || findUnmangledSymbol(F->getName()) ||
                            SectionMemoryManager::getSymbolAddressInProcess(F->getName()));
            }
        }
#endif
        // We need a memory manager to allocate memory and resolve symbols for this
        // new module. Create one that resolves symbols by looking back into the JIT.
        auto Resolver = orc::createLambdaResolver(
                          [&](const std::string &Name) {
                            // TODO: consider moving the FunctionMover resolver here
                            // Step 0: ObjectLinkingLayer has checked whether it is in the current module
                            // Step 1: See if it's something known to the ExecutionEngine
                            if (auto Sym = findSymbol(Name, true))
                              return RuntimeDyld::SymbolInfo(Sym.getAddress(),
                                                             Sym.getFlags());
                            // Step 2: Search the program symbols
                            if (uint64_t addr = SectionMemoryManager::getSymbolAddressInProcess(Name))
                                return RuntimeDyld::SymbolInfo(addr, JITSymbolFlags::Exported);
                            // Return failure code
                            return RuntimeDyld::SymbolInfo(nullptr);
                          },
                          [](const std::string &S) { return nullptr; }
                        );
        SmallVector<std::unique_ptr<Module>,1> Ms;
        Ms.push_back(std::move(M));
        auto modset = CompileLayer.addModuleSet(std::move(Ms), MemMgr,
                                                std::move(Resolver));
        // Force LLVM to emit the module so that we can register the symbols
        // in our lookup table.
        CompileLayer.emitAndFinalize(modset);
        return modset;
    }
Example #6
0
std::unique_ptr<std::vector<CFileEntry>>
CSelectWithMatching::select_in(std::unique_ptr<std::vector<CFileEntry>> data){

    //select only candidate files which are of equal file size like those
    //files in the matching vector
    std::unique_ptr<std::vector<CFileEntry>> input_selection(new std::vector<CFileEntry>);
    input_selection->reserve(m_matching->size());

    std::for_each(m_matching->begin(),
                  m_matching->end(),
                  [&data, &input_selection](const CFileEntry& elem){

        auto range = std::equal_range(data->begin(),
                                      data->end(),
                                      elem,
                                      [](const CFileEntry& lhs, const CFileEntry& rhs){
            return lhs.m_filesize < rhs.m_filesize;
        });

        if(range.first != data->end()){
            std::copy(range.first,
                      range.second,
                      std::back_inserter(*input_selection));
        }

    });

    std::copy(m_matching->begin(),
              m_matching->end(),
              std::back_inserter(*input_selection));

    std::sort(input_selection->begin(),
              input_selection->end(),
              [](const CFileEntry& lhs, const CFileEntry& rhs){
        return lhs.m_filesize < rhs.m_filesize;
    });

    return std::move(input_selection);
}
Example #7
0
// destructively move the contents of src into dest
// this assumes that the targets of the two modules are the same
// including the DataLayout and ModuleFlags (for example)
// and that there is no module-level assembly
static void jl_merge_module(Module *dest, std::unique_ptr<Module> src)
{
    assert(dest != src.get());
    for (Module::global_iterator I = src->global_begin(), E = src->global_end(); I != E;) {
        GlobalVariable *sG = &*I;
        GlobalValue *dG = dest->getNamedValue(sG->getName());
        ++I;
        // Replace a declaration with the definition:
        if (dG) {
            if (sG->isDeclaration()) {
                sG->replaceAllUsesWith(dG);
                sG->eraseFromParent();
                continue;
            }
            else {
                dG->replaceAllUsesWith(sG);
                dG->eraseFromParent();
            }
        }
        // Reparent the global variable:
        sG->removeFromParent();
        dest->getGlobalList().push_back(sG);
        // Comdat is owned by the Module, recreate it in the new parent:
        addComdat(sG);
    }

    for (Module::iterator I = src->begin(), E = src->end(); I != E;) {
        Function *sG = &*I;
        GlobalValue *dG = dest->getNamedValue(sG->getName());
        ++I;
        // Replace a declaration with the definition:
        if (dG) {
            if (sG->isDeclaration()) {
                sG->replaceAllUsesWith(dG);
                sG->eraseFromParent();
                continue;
            }
            else {
                dG->replaceAllUsesWith(sG);
                dG->eraseFromParent();
            }
        }
        // Reparent the global variable:
        sG->removeFromParent();
        dest->getFunctionList().push_back(sG);
        // Comdat is owned by the Module, recreate it in the new parent:
        addComdat(sG);
    }

    for (Module::alias_iterator I = src->alias_begin(), E = src->alias_end(); I != E;) {
        GlobalAlias *sG = &*I;
        GlobalValue *dG = dest->getNamedValue(sG->getName());
        ++I;
        if (dG) {
            if (!dG->isDeclaration()) { // aliases are always definitions, so this test is reversed from the above two
                sG->replaceAllUsesWith(dG);
                sG->eraseFromParent();
                continue;
            }
            else {
                dG->replaceAllUsesWith(sG);
                dG->eraseFromParent();
            }
        }
        sG->removeFromParent();
        dest->getAliasList().push_back(sG);
    }

    // metadata nodes need to be explicitly merged not just copied
    // so there are special passes here for each known type of metadata
    NamedMDNode *sNMD = src->getNamedMetadata("llvm.dbg.cu");
    if (sNMD) {
        NamedMDNode *dNMD = dest->getOrInsertNamedMetadata("llvm.dbg.cu");
#ifdef LLVM35
        for (NamedMDNode::op_iterator I = sNMD->op_begin(), E = sNMD->op_end(); I != E; ++I) {
            dNMD->addOperand(*I);
        }
#else
        for (unsigned i = 0, l = sNMD->getNumOperands(); i < l; i++) {
            dNMD->addOperand(sNMD->getOperand(i));
        }
#endif
    }
}
Example #8
0
  void CalculateReachingDefs(const std::unique_ptr<clang::CFG>& fn_cfg) {
    using bb_defs_map = llvm::DenseMap< const clang::CFGBlock*, defs_map >;
    
    defs_map all_defs = CollectAllDefs(fn_cfg);
    
    stmt_varref_map uses = CollectUses(fn_cfg);
    /*
    llvm::outs() << "stmt n uses:\n";
    for (auto e : uses) {
      clang::LangOptions LangOpts;
      clang::PrintingPolicy Policy(LangOpts);
      const Stmt* stmt = e.first;
      stmt->printPretty(llvm::outs(), 0, Policy);
      llvm::outs() << ":\n";
      for (auto u : e.second) {
	u->printPretty(llvm::outs(), 0, Policy);
	llvm::outs() << " ";
      }
      llvm::outs() << "\n";
    }
    llvm::outs() << "\n";*/
    
    bb_defs_map reach_out;
    bb_defs_map kills, gens;
    
    // local calculations (each block) for gen and kill
    for (auto itr = fn_cfg->begin(); itr != fn_cfg->end(); ++itr) {
      const clang::CFGBlock* b = *itr;
      
      // calculate gen, kill
      defs_map g = CalculateGen(b);
      defs_map k = CalculateKill(b, all_defs);
      /*
      llvm::outs() << b->getBlockID() << ": \n";
      llvm::outs() << "~~~~~~~~~~gens~~~~~~~~~~~\n";
      for (auto e: g) {
	if(const clang::VarDecl* vdecl = llvm::dyn_cast<clang::VarDecl>(e.first)) {
	  llvm::outs() << vdecl->getNameAsString() << ": ";
	  for (const Stmt* s : e.second) {
	    s->dumpPretty(*ast_ctx);
	    llvm::outs() << " ";
	  }
	  llvm::outs() << "\n";
	}
      }
      llvm::outs() << "\n~~~~~~~~~~kills~~~~~~~~~~~\n";
      for (auto e: k) {
	if(const clang::VarDecl* vdecl = llvm::dyn_cast<clang::VarDecl>(e.first)) {
	  llvm::outs() << vdecl->getNameAsString() << ": ";
	  for (const Stmt* s : e.second) {
	    s->dumpPretty(*ast_ctx);
	    llvm::outs() << " ";
	  }
	  llvm::outs() << "\n";
	}
      }
      llvm::outs() << "--------------------\n\n";
      */
      kills[b] = k;
      gens[b] = g;
      
      reach_out[b] = defs_map();
    }
    
    // global calculations on the entier cfg
    bool changed = true;
    while(changed) {
      changed = false;
      
      for (auto itr = fn_cfg->rbegin(); itr != fn_cfg->rend(); ++itr) {
	const clang::CFGBlock* b = *itr;
	
	auto newreaches = reach_out[b];
	
	defs_map reach_in;
	for (auto p_itr = b->pred_begin(); p_itr != b->pred_end(); ++p_itr) {
	  const clang::CFGBlock* p = *p_itr;
	  for (auto d : reach_out[p]) {
	    const clang::Decl* def_decl = d.first;
	    for (const clang::Stmt* stmt: d.second) {
	      reach_in[def_decl].insert(stmt);
	    }
	  }
	}
	
	/*
	llvm::outs() << "processing " << b->getBlockID() << "...\n";
	llvm::outs() << "-------------reach_in-----------\n";
	print_defs(reach_in);
	llvm::outs() << "-------------kills-----------\n";
	print_defs(kills[b]);
	llvm::outs() << "-------------gens-----------\n";
	print_defs(gens[b]);*/
	
	// newreaches = gen U (reach_in - kill)
	auto diff = def_diff(reach_in, kills[b]);
	auto gen_u_diff = def_union(gens[b], diff);
	newreaches = def_union(newreaches, gen_u_diff);
	
	/*
	llvm::outs() << "-------------diff-----------\n";
	print_defs(diff);*/
	
	newreaches = def_union(gens[b], diff);
	
	/*
	llvm::outs() << "-------------newreaches-----------\n";
	print_defs(newreaches);*/
	
	
	
	if (!equals(newreaches, reach_out[b])) {
	  /*
	  llvm::outs() << b->getBlockID() << ":\n";
	  llvm::outs() << "~~~~~~~~~~~~~~~newreaches~~~~~~~~~~~\n";
	  for (auto e : newreaches) {
	    if(const clang::VarDecl* vdecl = llvm::dyn_cast<clang::VarDecl>(e.first)) {
	      llvm::outs() << vdecl->getNameAsString() << ": ";
	      for (const Stmt* s : e.second) {
		s->dumpPretty(*ast_ctx);
		llvm::outs() << "\n";
	      }
	      llvm::outs() << "\n";
	    }
	  }
	  llvm::outs() << "\n";
	  llvm::outs() << "~~~~~~~~~~~~~~~reaches~~~~~~~~~~~\n";
	  for (auto e : reaches[b]) {
	    if(const clang::VarDecl* vdecl = llvm::dyn_cast<clang::VarDecl>(e.first)) {
	      llvm::outs() << vdecl->getNameAsString() << ": ";
	      for (const Stmt* s : e.second) {
		s->dumpPretty(*ast_ctx);
		llvm::outs() << "\n";
	      }
	      llvm::outs() << "\n";
	    }
	  }
	  llvm::outs() << "\n";
	  */
	  reach_out[b] = newreaches;
	  changed = true;
	}
      }
      
    } // end while
    
    /*
    llvm::outs() << "\n\n~~~~~~~~~~~~~~~~~~reaches~~~~~~~~~~~~~~~~~~~\n";
    for (auto r_e : reaches) {
      llvm::outs() << r_e.first->getBlockID() << ":\n";
      llvm::outs() << "--------------------------------------------\n";
      for (auto e : r_e.second) {
	if(const clang::VarDecl* vdecl = llvm::dyn_cast<clang::VarDecl>(e.first)) {
	  llvm::outs() << vdecl->getNameAsString() << ": \n";
	  for (const Stmt* s : e.second) {
	    s->dumpPretty(*ast_ctx);
	    llvm::outs() << "\n";
	  }
	  llvm::outs() << "\n";
	}
      }
      llvm::outs() << "--------------------------------------------\n\n";
    }*/
    
    bb_defs_map reach_in;
    for (auto itr = fn_cfg->rbegin(); itr != fn_cfg->rend(); ++itr) {
      const clang::CFGBlock* bb = *itr;
      defs_map d_in;
      
      for (auto p_itr = bb->pred_begin(); p_itr != bb->pred_end(); ++p_itr) {
	const clang::CFGBlock* p = *p_itr;
	for (auto d : reach_out[p]) {
	  const clang::Decl* def_decl = d.first;
	  std::copy(d.second.begin(), d.second.end(), std::inserter(d_in[def_decl], d_in[def_decl].begin()));
	}
      }
      
      reach_in[bb] = d_in;
    }
    
    /*
    llvm::outs() << "\n\n~~~~~~~~~~~~~~~~~~reach_in~~~~~~~~~~~~~~~~~~~\n";
    for (auto r_e : reach_in) {
      llvm::outs() << r_e.first->getBlockID() << ":\n";
      llvm::outs() << "--------------------------------------------\n";
      for (auto e : r_e.second) {
	if(const clang::VarDecl* vdecl = llvm::dyn_cast<clang::VarDecl>(e.first)) {
	  llvm::outs() << vdecl->getNameAsString() << ": \n";
	  for (const Stmt* s : e.second) {
	    s->dumpPretty(*ast_ctx);
	    llvm::outs() << "\n";
	  }
	  llvm::outs() << "\n";
	}
      }
      llvm::outs() << "--------------------------------------------\n\n";
    }*/
    
    // build use-def chains, need to calculate defs that reach uses locally
    llvm::DenseMap< const clang::DeclRefExpr*, const_stmt_set > use_def_chain;
    for (auto itr = fn_cfg->rbegin(); itr != fn_cfg->rend(); ++itr) {
      const clang::CFGBlock* bb = *itr;
      // get reach_in
      defs_map r_in = reach_in[bb];
      
      // go over the block and build use_def_chain for each use
      for (const clang::CFGElement e : *bb) {
	switch(e.getKind()) {
	  case clang::CFGElement::Statement: {
	    
	    const Stmt *stmt = e.castAs<CFGStmt>().getStmt();
	    // for all uses in this stmt, update use_def_chain
	    for (auto u : uses[stmt]) {
	      use_def_chain[u] = r_in[u->getDecl()];
	    }
	    // if stmt is a def, remove all killed defs from r_in
	    // we determine if the statement is a def by searching for this statement in all_defs
	    for (auto e : all_defs) {
	      if (std::find(e.second.begin(), e.second.end(), stmt) != e.second.end()) {
		// stmt us a def!
		const_stmt_set s; s.insert(stmt);
		r_in[e.first] = s;
	      }
	    }
	    break;
	  }
	  default: llvm_unreachable("cfg element not handled...");
	}
      }
      
    }
    
//     SourceManager sm = TheRewriter.getSourceMgr();
    // print def use info
    for (auto itr = fn_cfg->rbegin(); itr != fn_cfg->rend(); ++itr) {
      const clang::CFGBlock* bb = *itr;
      llvm::outs() << "-----------------------BB#" << bb->getBlockID() << "-----------------------\n";
      for (const clang::CFGElement e : *bb) {
	if (const Stmt *stmt = e.castAs<CFGStmt>().getStmt()) {
	  auto stmt_line = TheRewriter.getSourceMgr().getPresumedLineNumber(stmt->getLocStart());
	  llvm::outs() << "stmt line#" << stmt_line << ": ";
	  for (auto u : uses[stmt]) {
	    for (auto def_stmt : use_def_chain[u]) {
	      auto def_stmt_line = TheRewriter.getSourceMgr().getPresumedLineNumber(def_stmt->getLocStart());
	      llvm::outs() << def_stmt_line << " ";
	    }
	  }
	  llvm::outs() << "\n";
	}
      }
      llvm::outs() << "----------------------------------------------\n\n";
    }
    
  }
Example #9
0
  void CalculateControlDependence(const std::unique_ptr<clang::CFG>& fn_cfg) const {
    std::deque<CFGBlock*> wlist;
    std::copy(fn_cfg->begin(), fn_cfg->end(), std::back_inserter(wlist));
    /*
    const CFGBlock entry = fn_cfg->getEntry();
    const CFGBlock exit = fn_cfg->getExit();
    for (CFG::const_iterator itr = fn_cfg->begin(); itr != fn_cfg->end(); ++itr) {
      const CFGBlock blk = *itr;
    }
    
    while(!wlist.empty()) {
      CFGBlock* blk = wlist.front();
      wlist.pop_front();
      
      
      // if dataflow state changes, add successors
      for (const CFGElement e : *blk) {
	switch(e.getKind()) {
	  case CFGElement::Statement: {
	    break;
	  }
	  default: {
	    llvm_unreachable("CFGElement");
	  }
	}
      }
    }
    */
    
//     DominatorTree dt;
//     AnalysisDeclContextManager adcm;
//     AnalysisDeclContext adc(&adcm, fdecl);
//     dt.buildDominatorTree(adc);
//     fn_cfg.get()->print(llvm::outs(), LangOptions(), true);
//     llvm::outs() << "\n";
    llvm::DominatorTreeBase< clang::CFGBlock > pdomtree(true);
    pdomtree.recalculate(*(fn_cfg.get()));
//     pdomtree.print(llvm::outs());
    /*
    CFGBlock* root = pdomtree.getRoot();
    llvm::outs() << "root:\n";
    root->dump();
    llvm::outs() << "\n";
    llvm::SmallVector< CFGBlock*, 10 > desc;
    pdomtree.getDescendants(root, desc);
    llvm::outs() << "desc:\n";
    for (auto p : desc) {
      p->dump();
    }
    llvm::outs() << "----------------------\n\n";
    */
    
    std::deque< dtnb_type* > pre_visit;
    // topologically sort postdom tree, which is equivalent to preorder traversal
    pre(pdomtree.getRootNode(), pre_visit);
    
    std::reverse(pre_visit.begin(), pre_visit.end());
    llvm::outs() << "preorder: ";
    for (auto bid : pre_visit) {
      llvm::outs() << bid->getBlock()->getBlockID() << " ";
    }
    llvm::outs() << "\n";
    
    // Allen Kennedy algo
    llvm::DenseMap< dtnb_type*, llvm::SmallPtrSet< dtnb_type*, 20 > > CD;
    while (!pre_visit.empty()) {
      dtnb_type* x = pre_visit.front();
      pre_visit.pop_front();
      
      for (CFGBlock::const_pred_iterator p_itr = x->getBlock()->pred_begin(); p_itr != x->getBlock()->pred_end(); ++p_itr) {
	CFGBlock* p = *p_itr;
	dtnb_type* y = pdomtree.getNode(p);
	if (y->getIDom() != x) CD[x].insert(y);
      }
      
      for (dtnb_type* z : *x) {
	for (dtnb_type* y : CD[z]) {
	  if (y->getIDom() != x) CD[x].insert(y);
	}
      }
    }
    
    for (auto e : CD) {
      llvm::outs() << e.first->getBlock()->getBlockID() << ": ";
      for (auto cd : e.second) {
	llvm::outs() << cd->getBlock()->getBlockID() << " ";
      }
      llvm::outs() << "\n";
    }
  }
Example #10
0
	void prepare_out()
	{
		cur_out.reset(bucket_data_mem::create(65536, 0));
		str.next_out = (unsigned char*)cur_out->begin();
		str.avail_out = 65536;
	}
Example #11
0
void Viewer::mousePressEvent(QMouseEvent* event)
{
	if (event->modifiers() & Qt::ShiftModifier)
	{
		qoglviewer::Vec P;
		qoglviewer::Vec Q;
		rayClick(event,P,Q);

		Vec3 A(P[0],P[1],P[2]);
		Vec3 B(Q[0],Q[1],Q[2]);

		drawer_->new_list();
		switch(cell_picking)
		{
			case 0:
			{
				std::vector<Map2::Vertex> selected;
				cgogn::geometry::picking<Vec3>(map_,vertex_position_, A, B, selected);
				cgogn_log_info("picking_viewer") << "Selected vertices: "<< selected.size();
				if (!selected.empty())
				{
					drawer_->point_size_aa(4.0);
					drawer_->begin(GL_POINTS);
					// closest point in red
					drawer_->color3f(1.0,0.0,0.0);
					drawer_->vertex3fv(vertex_position_[selected[0]]);
					// others in yellow
					drawer_->color3f(1.0,1.0,0.0);
					for(uint32 i=1u;i<selected.size();++i)
						drawer_->vertex3fv(vertex_position_[selected[i]]);
					drawer_->end();
				}
			}
			break;
			case 1:
			{
				std::vector<Map2::Edge> selected;
				cgogn::geometry::picking<Vec3>(map_, vertex_position_, A, B, selected);
				cgogn_log_info("picking_viewer") << "Selected edges: "<< selected.size();
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0, 0.0, 0.0);
					cgogn::rendering::add_to_drawer<Vec3>(map_, selected[0], vertex_position_, drawer_.get());
					// others in yellow
					drawer_->color3f(1.0, 1.0, 0.0);
					for(uint32 i = 1u; i < selected.size(); ++i)
						cgogn::rendering::add_to_drawer<Vec3>(map_, selected[i], vertex_position_, drawer_.get());
					drawer_->end();
				}
			}
			break;
			case 2:
			{
				std::vector<Map2::Face> selected;
				cgogn::geometry::picking<Vec3>(map_, vertex_position_, A, B, selected);
				cgogn_log_info("picking_viewer") << "Selected faces: "<< selected.size();
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0, 0.0, 0.0);
					cgogn::rendering::add_to_drawer<Vec3>(map_, selected[0], vertex_position_, drawer_.get());
					// others in yellow
					drawer_->color3f(1.0, 1.0, 0.0);
					for(uint32 i = 1u; i < selected.size(); ++i)
						cgogn::rendering::add_to_drawer<Vec3>(map_, selected[i], vertex_position_, drawer_.get());
					drawer_->end();
				}
			}
			break;
			case 3:
			{
				std::vector<Map2::Volume> selected;
				cgogn::geometry::picking<Vec3>(map_, vertex_position_, A, B, selected);
				cgogn_log_info("picking_viewer") << "Selected volumes: "<< selected.size();
				if (!selected.empty())
				{
					drawer_->line_width(2.0);
					drawer_->begin(GL_LINES);
					// closest face in red
					drawer_->color3f(1.0, 0.0, 0.0);
					cgogn::rendering::add_to_drawer<Vec3>(map_, selected[0], vertex_position_, drawer_.get());
					// others in yellow
					drawer_->color3f(1.0, 1.0, 0.0);
					for(uint32 i = 1u; i < selected.size(); ++i)
						cgogn::rendering::add_to_drawer<Vec3>(map_, selected[i], vertex_position_, drawer_.get());
					drawer_->end();
				}
			}
			break;
		}
		drawer_->line_width(4.0);
		drawer_->begin(GL_LINES);
		drawer_->color3f(1.0, 0.0, 1.0);
		drawer_->vertex3fv(A);
		drawer_->vertex3fv(B);
		drawer_->end();
		drawer_->end_list();
	}

	QOGLViewer::mousePressEvent(event);
}