Пример #1
0
static void test(hwloc_const_bitmap_t cpuset, int flags)
{
  hwloc_bitmap_t new_cpuset = hwloc_bitmap_alloc();
  result_set("Bind this singlethreaded process", hwloc_set_cpubind(topology, cpuset, flags), support->cpubind->set_thisproc_cpubind || support->cpubind->set_thisthread_cpubind);
  result_get("Get  this singlethreaded process", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags), support->cpubind->get_thisproc_cpubind || support->cpubind->get_thisthread_cpubind);
  result_set("Bind this thread", hwloc_set_cpubind(topology, cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->set_thisthread_cpubind);
  result_get("Get  this thread", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->get_thisthread_cpubind);
  result_set("Bind this whole process", hwloc_set_cpubind(topology, cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_thisproc_cpubind);
  result_get("Get  this whole process", cpuset, new_cpuset, hwloc_get_cpubind(topology, new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_thisproc_cpubind);

#ifdef HWLOC_WIN_SYS
  result_set("Bind process", hwloc_set_proc_cpubind(topology, GetCurrentProcess(), cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_proc_cpubind);
  result_get("Get  process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, GetCurrentProcess(), new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_proc_cpubind);
  result_set("Bind thread", hwloc_set_thread_cpubind(topology, GetCurrentThread(), cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->set_thread_cpubind);
  result_get("Get  thread", cpuset, new_cpuset, hwloc_get_thread_cpubind(topology, GetCurrentThread(), new_cpuset, flags | HWLOC_CPUBIND_THREAD), support->cpubind->get_thread_cpubind);
#else /* !HWLOC_WIN_SYS */
  result_set("Bind whole process", hwloc_set_proc_cpubind(topology, getpid(), cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->set_proc_cpubind);
  result_get("Get  whole process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, getpid(), new_cpuset, flags | HWLOC_CPUBIND_PROCESS), support->cpubind->get_proc_cpubind);
  result_set("Bind process", hwloc_set_proc_cpubind(topology, getpid(), cpuset, flags), support->cpubind->set_proc_cpubind);
  result_get("Get  process", cpuset, new_cpuset, hwloc_get_proc_cpubind(topology, getpid(), new_cpuset, flags), support->cpubind->get_proc_cpubind);
#ifdef hwloc_thread_t
  result_set("Bind thread", hwloc_set_thread_cpubind(topology, pthread_self(), cpuset, flags), support->cpubind->set_thread_cpubind);
  result_get("Get  thread", cpuset, new_cpuset, hwloc_get_thread_cpubind(topology, pthread_self(), new_cpuset, flags), support->cpubind->get_thread_cpubind);
#endif
#endif /* !HWLOC_WIN_SYS */
  printf("\n");
  hwloc_bitmap_free(new_cpuset);
}
Пример #2
0
static void testmem(hwloc_const_bitmap_t nodeset, hwloc_membind_policy_t policy, int flags, int expected)
{
  hwloc_bitmap_t new_nodeset = hwloc_bitmap_alloc();
  hwloc_membind_policy_t newpolicy;
  void *area;
  size_t area_size = 1024;
  result_set("Bind this singlethreaded process memory", hwloc_set_membind(topology, nodeset, policy, flags), (support->membind->set_thisproc_membind || support->membind->set_thisthread_membind) && expected);
  result_get("Get  this singlethreaded process memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags), (support->membind->get_thisproc_membind || support->membind->get_thisthread_membind) && expected);
  result_set("Bind this thread memory", hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_THREAD), support->membind->set_thisproc_membind && expected);
  result_get("Get  this thread memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags | HWLOC_MEMBIND_THREAD), support->membind->get_thisproc_membind && expected);
  result_set("Bind this whole process memory", hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_PROCESS), support->membind->set_thisproc_membind && expected);
  result_get("Get  this whole process memory", nodeset, new_nodeset, hwloc_get_membind(topology, new_nodeset, &newpolicy, flags | HWLOC_MEMBIND_PROCESS), support->membind->get_thisproc_membind && expected);
#ifdef HWLOC_WIN_SYS
  result_set("Bind process memory", hwloc_set_proc_membind(topology, GetCurrentProcess(), nodeset, policy, flags), support->membind->set_proc_membind && expected);
  result_get("Get  process memory", nodeset, new_nodeset, hwloc_get_proc_membind(topology, GetCurrentProcess(), new_nodeset, &newpolicy, flags), support->membind->get_proc_membind && expected);
#else /* !HWLOC_WIN_SYS */
  result_set("Bind process memory", hwloc_set_proc_membind(topology, getpid(), nodeset, policy, flags), support->membind->set_proc_membind && expected);
  result_get("Get  process memory", nodeset, new_nodeset, hwloc_get_proc_membind(topology, getpid(), new_nodeset, &newpolicy, flags), support->membind->get_proc_membind && expected);
#endif /* !HWLOC_WIN_SYS */
  result_set("Bind area", hwloc_set_area_membind(topology, &new_nodeset, sizeof(new_nodeset), nodeset, policy, flags), support->membind->set_area_membind && expected);
  result_get("Get  area", nodeset, new_nodeset, hwloc_get_area_membind(topology, &new_nodeset, sizeof(new_nodeset), new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected);
  if (!(flags & HWLOC_MEMBIND_MIGRATE)) {
    result_set("Alloc bound area", (area = hwloc_alloc_membind(topology, area_size, nodeset, policy, flags)) == NULL, (support->membind->alloc_membind && expected) || !(flags & HWLOC_MEMBIND_STRICT));
    if (area) {
      memset(area, 0, area_size);
      result_get("Get   bound area", nodeset, new_nodeset, hwloc_get_area_membind(topology, area, area_size, new_nodeset, &newpolicy, flags), support->membind->get_area_membind && expected);
      result_get("Free  bound area", NULL, NULL, hwloc_free(topology, area, area_size), support->membind->alloc_membind && expected);
    }
  }
  printf("\n");
  hwloc_bitmap_free(new_nodeset);
}
std::vector<Result> ResultGenerator::findResults(const std::string &text, int duplicateProximity, ResultGenerator::Verbosity verbosity, ResultGenerator::Statistics *statistics) {
    std::vector<Result> results;
#ifdef CPUTIMER
    Timer timer, timerOverFunction;
    int64_t cputime, walltime;
#endif // CPUTIMER

#ifdef CPUTIMER
    timer.start();
    timerOverFunction.start();
#endif // CPUTIMER
    const std::vector<std::string> words = tokenizer->read_words(text, Tokenizer::Duplicates);
    const std::vector<std::string> word_combinations = tokenizer->generate_word_combinations(words, 3 /** TODO configurable */);
    Error::info("Identified %d words, resulting in %d word combinations", words.size(), word_combinations.size());
    if (statistics != nullptr) {
        statistics->word_count = words.size();
        statistics->word_combinations_count = word_combinations.size();
    }
#ifdef CPUTIMER
    if (verbosity > VerbositySilent) {
        timer.elapsed(&cputime, &walltime);
        Error::info("Spent CPU time to tokenize text of length %d: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", text.length(), cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
    }
#endif // CPUTIMER

    /// ===================================================================================
    /// Check if the test input contains road labels (e.g. 'E 20') and city/town names.
    /// Then determine the clostest distance between any city/town and any identified road.
    /// If distance is below an acceptable threshold, assume location on road closest to
    /// town as resulting position.
    /// -----------------------------------------------------------------------------------
    if (verbosity > VerbositySilent) {
        Error::info("=== Testing for roads close to cities/towns ===");
#ifdef CPUTIMER
        timer.start();
#endif // CPUTIMER
    }

    const std::vector<struct Sweden::Road> identifiedRoads = sweden->identifyRoads(words);
    Error::info("Identified roads: %d", identifiedRoads.size());
    const std::vector<struct TokenProcessor::RoadMatch> roadMatches = tokenProcessor->evaluteRoads(word_combinations, identifiedRoads);
    Error::info("Identified road matches: %d", roadMatches.size());

    for (const TokenProcessor::RoadMatch &roadMatch : roadMatches) {
        const int distance = roadMatch.distance;

        if (distance < 10000) {
            /// Closer than 10km
            Coord c;
            if (node2Coord->retrieve(roadMatch.bestRoadNode, c)) {
                Result r(c, roadMatch.quality, std::string("roadMatch: road:") + static_cast<std::string>(roadMatch.road) + " near " + roadMatch.word_combination);
                r.elements.push_back(OSMElement(roadMatch.bestRoadNode, OSMElement::Node, OSMElement::UnknownRealWorldType));
                r.elements.push_back(OSMElement(roadMatch.bestWordNode, OSMElement::Node, OSMElement::UnknownRealWorldType));
                results.push_back(r);
                if (verbosity > VerbositySilent)
                    Error::debug("Distance between '%s' and road %s: %.1f km (between road node %llu and word's node %llu)", roadMatch.word_combination.c_str(), roadMatch.road.operator std::string().c_str(), distance / 1000.0, roadMatch.bestRoadNode, roadMatch.bestWordNode);
            }
        }
    }
#ifdef CPUTIMER
    if (verbosity > VerbositySilent) {
        timer.elapsed(&cputime, &walltime);
        Error::info("Spent CPU time to identify roads close to cities/towns: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
    }
#endif // CPUTIMER


    if (verbosity > VerbositySilent) {
        Error::info("=== Testing for places inside administrative boundaries ===");
#ifdef CPUTIMER
        timer.start();
#endif // CPUTIMER
    }
    const std::vector<struct Sweden::KnownAdministrativeRegion> adminReg = sweden->identifyAdministrativeRegions(word_combinations);
    Error::info("Identified administrative regions: %d", adminReg.size());
    if (!adminReg.empty()) {
        const std::vector<struct TokenProcessor::AdminRegionMatch> adminRegionMatches = tokenProcessor->evaluateAdministrativeRegions(adminReg, word_combinations);
        Error::info("Identified administrative region matches: %d", adminReg.size());
        for (const auto &adminRegionMatch : adminRegionMatches) {
            Coord c;
            if (getCenterOfOSMElement(adminRegionMatch.match, c)) {
                WriteableString matchName("UNSET");
                switch (adminRegionMatch.match.type) {
                case OSMElement::Node: nodeNames->retrieve(adminRegionMatch.match.id, matchName); break;
                case OSMElement::Way: wayNames->retrieve(adminRegionMatch.match.id, matchName); break;
                case OSMElement::Relation: relationNames->retrieve(adminRegionMatch.match.id, matchName); break;
                case OSMElement::UnknownElementType: matchName = WriteableString("Unknown"); break;
                }

                Result r(c, adminRegionMatch.quality * .95, std::string("Places inside admin bound: ") + adminRegionMatch.adminRegion.name + " (relation " + std::to_string(adminRegionMatch.adminRegion.relationId) + ") > '" + matchName + "' (" + adminRegionMatch.match.operator std::string() + ", found via: '" + adminRegionMatch.combined + "')");
                r.elements.push_back(OSMElement(adminRegionMatch.adminRegion.relationId, OSMElement::Relation));
                r.elements.push_back(adminRegionMatch.match);
                results.push_back(r);
                if (verbosity > VerbositySilent)
                    Error::debug("Found place '%s' (%s) inside admin region '%s' (%d) via combination '%s'", matchName.c_str(), adminRegionMatch.match.operator std::string().c_str(), adminRegionMatch.adminRegion.name.c_str(), adminRegionMatch.adminRegion.relationId, adminRegionMatch.combined.c_str(), adminRegionMatch.combined.c_str());
            }
        }
    }
#ifdef CPUTIMER
    if (verbosity > VerbositySilent) {
        timer.elapsed(&cputime, &walltime);
        Error::info("Spent CPU time to identify places inside administrative boundaries: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
    }
#endif // CPUTIMER

    if (verbosity > VerbositySilent) {
        Error::info("=== Testing for local-scope places near global-scope places ===");
#ifdef CPUTIMER
        timer.start();
#endif // CPUTIMER
    }
    std::vector<struct OSMElement> globalPlaces = sweden->identifyPlaces(word_combinations);
    Error::info("Identified global places: %d", globalPlaces.size());
    if (!globalPlaces.empty()) {
        const OSMElement::RealWorldType firstRwt = globalPlaces.front().realworld_type;
        for (auto it = ++globalPlaces.cbegin(); it != globalPlaces.cend();) {
            if (it->realworld_type != firstRwt)
                it = globalPlaces.erase(it);
            else
                ++it;
        }
        const std::vector<struct TokenProcessor::LocalPlaceMatch> localPlacesMatches = tokenProcessor->evaluateNearPlaces(word_combinations, globalPlaces);
        Error::info("Identified local places matches: %d", localPlacesMatches.size());
        for (const auto &localPlacesMatch : localPlacesMatches) {
            Coord c;
            if (getCenterOfOSMElement(localPlacesMatch.local, c)) {
                Result r(c, localPlacesMatch.quality * .75, std::string("Local near global place: ") + localPlacesMatch.local.operator std::string() + " ('" + localPlacesMatch.local.name() + "') near " + localPlacesMatch.global.operator std::string() + " ('" + localPlacesMatch.global.name() + "')");
                r.elements.push_back(localPlacesMatch.global);
                r.elements.push_back(localPlacesMatch.local);
                results.push_back(r);
                if (verbosity > VerbositySilent)
                    Error::debug("Got a result for global place '%s' and local place '%s'", localPlacesMatch.global.operator std::string().c_str(), localPlacesMatch.local.operator std::string().c_str());
            }
        }
    }
#ifdef CPUTIMER
    if (verbosity > VerbositySilent) {
        timer.elapsed(&cputime, &walltime);
        Error::info("Spent CPU time to identify local/global places: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
    }
#endif // CPUTIMER


    if (verbosity > VerbositySilent) {
        Error::info("=== Testing word combination occurring only once (unique) in OSM data ===");
#ifdef CPUTIMER
        timer.start();
#endif // CPUTIMER
    }
    std::vector<struct TokenProcessor::UniqueMatch> uniqueMatches = tokenProcessor->evaluateUniqueMatches(word_combinations);
    Error::info("Identified unique matches: %d", uniqueMatches.size());
    for (const auto &uniqueMatch : uniqueMatches) {
        Coord c;
        if (getCenterOfOSMElement(uniqueMatch.element, c)) {
            Result r(c, uniqueMatch.quality * .8, std::string("Unique name '") + uniqueMatch.element.name().c_str() + "' (" + uniqueMatch.element.operator std::string() + ") found via '" + uniqueMatch.combined + "'");
            r.elements.push_back(uniqueMatch.element);
            results.push_back(r);
            if (verbosity > VerbositySilent)
                Error::debug("Got a result for combined word '%s': %s (%s)", uniqueMatch.combined.c_str(), uniqueMatch.element.name().c_str(), uniqueMatch.element.operator std::string().c_str());
        }
    }
#ifdef CPUTIMER
    if (verbosity > VerbositySilent) {
        timer.elapsed(&cputime, &walltime);
        Error::info("Spent CPU time to identify unique places: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
    }
#endif // CPUTIMER


    if (!globalPlaces.empty()) {
        /// No good result found, but some places have been recognized in the process.
        /// Pick one of the larger places as result.
        if (verbosity > VerbositySilent) {
            Error::info("=== Testing any known places, trying to pick a good one ===");
#ifdef CPUTIMER
            timer.start();
#endif // CPUTIMER
        }
        // FIXME picking the right place from the list is rather ugly. Can do better?
        OSMElement bestPlace;
        OSMElement::RealWorldType rwt = OSMElement::PlaceSmall;
        for (const OSMElement &place : globalPlaces) {
            if (place.realworld_type == OSMElement::PlaceMedium && rwt >= OSMElement::PlaceSmall) {
                bestPlace = place;
                rwt = place.realworld_type;
            } else if (place.realworld_type < OSMElement::PlaceMedium && rwt >= OSMElement::PlaceMedium) {
                bestPlace = place;
                rwt = place.realworld_type;
            } else if (rwt != OSMElement::PlaceLarge && place.realworld_type == OSMElement::PlaceLargeArea) {
                bestPlace = place;
                rwt = place.realworld_type;
            } else if (rwt == OSMElement::PlaceLargeArea && place.realworld_type == OSMElement::PlaceLarge) {
                bestPlace = place;
                rwt = place.realworld_type;
            }
        }

        if (bestPlace.isValid()) {
            const double quality = rwt == OSMElement::PlaceLarge ? 1.0 : (rwt == OSMElement::PlaceMedium?.9 : (rwt == OSMElement::PlaceLargeArea?.6 : (rwt == OSMElement::PlaceSmall?.8 : .5)));
            Coord c;
            if (getCenterOfOSMElement(bestPlace, c)) {
                Result r(c, quality * .5, std::string("Large place: ") + bestPlace.name() + " (" + bestPlace.operator std::string() + ")");
                r.elements.push_back(bestPlace);
                results.push_back(r);
                if (verbosity > VerbositySilent)
                    Error::debug("Best place is %s (%s)", bestPlace.name().c_str(), bestPlace.operator std::string().c_str());
            }
        }
#ifdef CPUTIMER
        if (verbosity > VerbositySilent) {
            timer.elapsed(&cputime, &walltime);
            Error::info("Spent CPU time to identify known places: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
        }
#endif // CPUTIMER
    }


    if (!results.empty()) {
        if (verbosity > VerbositySilent) {
            Error::info("=== Sorting and cleaning results ===");
#ifdef CPUTIMER
            timer.start();
#endif // CPUTIMER
        }
        if (duplicateProximity > 0) {
            const int64_t duplicateProximitySquare = (int64_t)duplicateProximity * (int64_t)duplicateProximity;
            /// Remove results close to even better results
            std::unordered_set<Result> result_set(results.cbegin(), results.cend());
            for (auto outer = result_set.cbegin(); outer != result_set.cend();) {
                bool removedOuter = false;
                const Result &outerR = *outer;
                for (auto inner = result_set.cbegin(); !removedOuter && inner != result_set.cend(); ++inner) {
                    if (inner == outer) continue;
                    const Result &innerR = *inner;
                    if (outerR.quality > innerR.quality) continue; ///< avoid removing results of higher quality
                    const auto d = Coord::distanceXYsquare(outerR.coord, innerR.coord);
                    if (d < duplicateProximitySquare) {
                        /// Less than x meters away? Remove this result!
                        outer = result_set.erase(outer);
                        removedOuter = true;
                    }
                }
                if (!removedOuter)
                    ++outer;
            }
            results.assign(result_set.cbegin(), result_set.cend());
        }
        /// Sort results by quality (highest first)
        std::sort(results.begin(), results.end(), [](Result & a, Result & b) {
            return a.quality > b.quality;
        });
#ifdef CPUTIMER
        if (verbosity > VerbositySilent) {
            timer.elapsed(&cputime, &walltime);
            Error::info("Spent CPU time to clean/sort results: %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
        }
#endif // CPUTIMER
    }

#ifdef CPUTIMER
    timerOverFunction.elapsed(&cputime, &walltime);
    Error::info("%d results, time %.1fms == %.1fs  (wall time: %.1fms == %.1fs)", results.size(), cputime / 1000.0, cputime / 1000000.0, walltime / 1000.0, walltime / 1000000.0);
#else // CPUTIMER
    Error::debug("%d results", results.size());
#endif // CPUTIMER

    if (verbosity > VerbositySilent)
        Error::info("=== Done generating results ===");

    return results;
}