<commit_before>#include "config.h"

#include "selutility.hpp"

#include <charconv>
#include <chrono>
#include <filesystem>
#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <vector>
#include <xyz/openbmc_project/Common/error.hpp>

extern const ipmi::sensor::InvObjectIDMap invSensors;
using namespace phosphor::logging;
using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

namespace
{

constexpr auto systemEventRecord = 0x02;

} // namespace

namespace ipmi
{

namespace sel
{

namespace internal
{

inline bool isRecordOEM(uint8_t recordType)
{
    return recordType != systemEventRecord;
}

/** Parse the entry with format like key=val */
std::pair<std::string, std::string> parseEntry(const std::string& entry)
{
    constexpr auto equalSign = "=";
    auto pos = entry.find(equalSign);
    assert(pos != std::string::npos);
    auto key = entry.substr(0, pos);
    auto val = entry.substr(pos + 1);
    return {key, val};
}

std::map<std::string, std::string>
    parseAdditionalData(const AdditionalData& data)
{
    std::map<std::string, std::string> ret;

    for (const auto& d : data)
    {
        ret.insert(parseEntry(d));
    }
    return ret;
}

uint8_t convert(const std::string_view& str, int base = 10)
{
    int ret;
    std::from_chars(str.data(), str.data() + str.size(), ret, base);
    return static_cast<uint8_t>(ret);
}

// Convert the string to a vector of uint8_t, where the str is formatted as hex
std::vector<uint8_t> convertVec(const std::string_view& str)
{
    std::vector<uint8_t> ret;
    auto len = str.size() / 2;
    ret.reserve(len);
    for (size_t i = 0; i < len; ++i)
    {
        ret.emplace_back(convert(str.substr(i * 2, 2), 16));
    }
    return ret;
}

GetSELEntryResponse
    prepareSELEntry(const std::string& objPath,
                    ipmi::sensor::InvObjectIDMap::const_iterator iter)
{
    GetSELEntryResponse record{};

    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
    auto service = ipmi::getService(bus, logEntryIntf, objPath);

    // Read all the log entry properties.
    auto methodCall = bus.new_method_call(service.c_str(), objPath.c_str(),
                                          propIntf, "GetAll");
    methodCall.append(logEntryIntf);

    auto reply = bus.call(methodCall);
    if (reply.is_method_error())
    {
        log<level::ERR>("Error in reading logging property entries");
        elog<InternalFailure>();
    }

    std::map<PropertyName, PropertyType> entryData;
    reply.read(entryData);

    // Read Id from the log entry.
    static constexpr auto propId = "Id";
    auto iterId = entryData.find(propId);
    if (iterId == entryData.end())
    {
        log<level::ERR>("Error in reading Id of logging entry");
        elog<InternalFailure>();
    }

    // Read Timestamp from the log entry.
    static constexpr auto propTimeStamp = "Timestamp";
    auto iterTimeStamp = entryData.find(propTimeStamp);
    if (iterTimeStamp == entryData.end())
    {
        log<level::ERR>("Error in reading Timestamp of logging entry");
        elog<InternalFailure>();
    }
    std::chrono::milliseconds chronoTimeStamp(
        std::get<uint64_t>(iterTimeStamp->second));

    if (iter == invSensors.end())
    {
        // It is expected to be a custom SEL entry
        record.event.oemCD.recordID =
            static_cast<uint16_t>(std::get<uint32_t>(iterId->second));
        static constexpr auto propAdditionalData = "AdditionalData";
        // static constexpr auto strEventDir = "EVENT_DIR";
        // static constexpr auto strGenerateId = "GENERATOR_ID";
        static constexpr auto strRecordType = "RECORD_TYPE";
        static constexpr auto strSensorData = "SENSOR_DATA";
        // static constexpr auto strSensorPath = "SENSOR_PATH";
        iterId = entryData.find(propAdditionalData);
        if (iterId == entryData.end())
        {
            log<level::ERR>("Error finding AdditionalData");
            elog<InternalFailure>();
        }
        const auto& addData = std::get<AdditionalData>(iterId->second);
        auto m = parseAdditionalData(addData);
        auto recordType = convert(m[strRecordType]);
        auto isOEM = isRecordOEM(recordType);
        if (isOEM)
        {
            if (recordType >= 0xC0 && recordType < 0xE0)
            {
                record.event.oemCD.timeStamp = static_cast<uint32_t>(
                    std::chrono::duration_cast<std::chrono::seconds>(
                        chronoTimeStamp)
                        .count());
                record.event.oemCD.recordType = recordType;
                // The ManufactureID and OEM Defined are packed in the sensor
                // data
                auto sensorData = convertVec(m[strSensorData]);
                // Fill the 9 bytes of Manufacture ID and oemDefined
                memcpy(&record.event.oemCD.manufacturerID, sensorData.data(),
                       std::min(sensorData.size(), static_cast<size_t>(9)));
            }
            else if (recordType >= 0xE0)
            {
                // TODO
            }
        }
        else
        {
            // TODO
        }
    }
    else
    {

        record.event.eventRecord.recordID =
            static_cast<uint16_t>(std::get<uint32_t>(iterId->second));
        record.event.eventRecord.timeStamp = static_cast<uint32_t>(
            std::chrono::duration_cast<std::chrono::seconds>(chronoTimeStamp)
                .count());

        static constexpr auto generatorID = 0x2000;
        static constexpr auto eventMsgRevision = 0x04;

        record.event.eventRecord.recordType = systemEventRecord;
        record.event.eventRecord.generatorID = generatorID;
        record.event.eventRecord.eventMsgRevision = eventMsgRevision;

        record.event.eventRecord.sensorType = iter->second.sensorType;
        record.event.eventRecord.sensorNum = iter->second.sensorID;
        record.event.eventRecord.eventData1 = iter->second.eventOffset;

        // Read Resolved from the log entry.
        static constexpr auto propResolved = "Resolved";
        auto iterResolved = entryData.find(propResolved);
        if (iterResolved == entryData.end())
        {
            log<level::ERR>("Error in reading Resolved field of logging entry");
            elog<InternalFailure>();
        }

        static constexpr auto deassertEvent = 0x80;

        // Evaluate if the event is assertion or deassertion event
        if (std::get<bool>(iterResolved->second))
        {
            record.event.eventRecord.eventType =
                deassertEvent | iter->second.eventReadingType;
        }
        else
        {
            record.event.eventRecord.eventType = iter->second.eventReadingType;
        }
    }

    return record;
}

} // namespace internal

GetSELEntryResponse convertLogEntrytoSEL(const std::string& objPath)
{
    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};

    static constexpr auto assocIntf =
        "xyz.openbmc_project.Association.Definitions";
    static constexpr auto assocProp = "Associations";

    auto service = ipmi::getService(bus, assocIntf, objPath);

    // Read the Associations interface.
    auto methodCall =
        bus.new_method_call(service.c_str(), objPath.c_str(), propIntf, "Get");
    methodCall.append(assocIntf);
    methodCall.append(assocProp);

    auto reply = bus.call(methodCall);
    if (reply.is_method_error())
    {
        log<level::ERR>("Error in reading Associations interface");
        elog<InternalFailure>();
    }

    using AssociationList =
        std::vector<std::tuple<std::string, std::string, std::string>>;

    std::variant<AssociationList> list;
    reply.read(list);

    auto& assocs = std::get<AssociationList>(list);

    /*
     * Check if the log entry has any callout associations, if there is a
     * callout association try to match the inventory path to the corresponding
     * IPMI sensor.
     */
    for (const auto& item : assocs)
    {
        if (std::get<0>(item).compare(CALLOUT_FWD_ASSOCIATION) == 0)
        {
            auto iter = invSensors.find(std::get<2>(item));
            if (iter == invSensors.end())
            {
                iter = invSensors.find(BOARD_SENSOR);
                if (iter == invSensors.end())
                {
                    log<level::ERR>("Motherboard sensor not found");
                    elog<InternalFailure>();
                }
            }

            return internal::prepareSELEntry(objPath, iter);
        }
    }

    // If there are no callout associations link the log entry to system event
    // sensor
    auto iter = invSensors.find(SYSTEM_SENSOR);
    return internal::prepareSELEntry(objPath, iter);
}

std::chrono::seconds getEntryTimeStamp(const std::string& objPath)
{
    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};

    auto service = ipmi::getService(bus, logEntryIntf, objPath);

    using namespace std::string_literals;
    static const auto propTimeStamp = "Timestamp"s;

    auto methodCall =
        bus.new_method_call(service.c_str(), objPath.c_str(), propIntf, "Get");
    methodCall.append(logEntryIntf);
    methodCall.append(propTimeStamp);

    auto reply = bus.call(methodCall);
    if (reply.is_method_error())
    {
        log<level::ERR>("Error in reading Timestamp from Entry interface");
        elog<InternalFailure>();
    }

    std::variant<uint64_t> timeStamp;
    reply.read(timeStamp);

    std::chrono::milliseconds chronoTimeStamp(std::get<uint64_t>(timeStamp));

    return std::chrono::duration_cast<std::chrono::seconds>(chronoTimeStamp);
}

void readLoggingObjectPaths(ObjectPaths& paths)
{
    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
    auto depth = 0;
    paths.clear();

    auto mapperCall = bus.new_method_call(mapperBusName, mapperObjPath,
                                          mapperIntf, "GetSubTreePaths");
    mapperCall.append(logBasePath);
    mapperCall.append(depth);
    mapperCall.append(ObjectPaths({logEntryIntf}));

    auto reply = bus.call(mapperCall);
    if (reply.is_method_error())
    {
        log<level::INFO>("Error in reading logging entry object paths");
    }
    else
    {
        reply.read(paths);

        std::sort(paths.begin(), paths.end(),
                  [](const std::string& a, const std::string& b) {
                      namespace fs = std::filesystem;
                      fs::path pathA(a);
                      fs::path pathB(b);
                      auto idA = std::stoul(pathA.filename().string());
                      auto idB = std::stoul(pathB.filename().string());

                      return idA < idB;
                  });
    }
}

} // namespace sel

} // namespace ipmi
<commit_msg>sel: Support OEM record 0xE0~0xFF<commit_after>#include "config.h"

#include "selutility.hpp"

#include <charconv>
#include <chrono>
#include <filesystem>
#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <vector>
#include <xyz/openbmc_project/Common/error.hpp>

extern const ipmi::sensor::InvObjectIDMap invSensors;
using namespace phosphor::logging;
using InternalFailure =
    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

namespace
{

constexpr auto systemEventRecord = 0x02;

constexpr auto propAdditionalData = "AdditionalData";
constexpr auto strEventDir = "EVENT_DIR";
constexpr auto strGenerateId = "GENERATOR_ID";
constexpr auto strRecordType = "RECORD_TYPE";
constexpr auto strSensorData = "SENSOR_DATA";
constexpr auto strSensorPath = "SENSOR_PATH";

} // namespace

namespace ipmi
{

namespace sel
{

namespace internal
{

inline bool isRecordOEM(uint8_t recordType)
{
    return recordType != systemEventRecord;
}

using additionalDataMap = std::map<std::string, std::string>;
/** Parse the entry with format like key=val */
std::pair<std::string, std::string> parseEntry(const std::string& entry)
{
    constexpr auto equalSign = "=";
    auto pos = entry.find(equalSign);
    assert(pos != std::string::npos);
    auto key = entry.substr(0, pos);
    auto val = entry.substr(pos + 1);
    return {key, val};
}

additionalDataMap parseAdditionalData(const AdditionalData& data)
{
    std::map<std::string, std::string> ret;

    for (const auto& d : data)
    {
        ret.insert(parseEntry(d));
    }
    return ret;
}

uint8_t convert(const std::string_view& str, int base = 10)
{
    int ret;
    std::from_chars(str.data(), str.data() + str.size(), ret, base);
    return static_cast<uint8_t>(ret);
}

// Convert the string to a vector of uint8_t, where the str is formatted as hex
std::vector<uint8_t> convertVec(const std::string_view& str)
{
    std::vector<uint8_t> ret;
    auto len = str.size() / 2;
    ret.reserve(len);
    for (size_t i = 0; i < len; ++i)
    {
        ret.emplace_back(convert(str.substr(i * 2, 2), 16));
    }
    return ret;
}

/** Construct OEM SEL record according to IPMI spec 32.2, 32.3. */
void constructOEMSel(uint8_t recordType, std::chrono::milliseconds timestamp,
                     const additionalDataMap& m, GetSELEntryResponse& record)
{
    auto dataIter = m.find(strSensorData);
    assert(dataIter != m.end());
    auto sensorData = convertVec(dataIter->second);
    if (recordType >= 0xC0 && recordType < 0xE0)
    {
        record.event.oemCD.timeStamp = static_cast<uint32_t>(
            std::chrono::duration_cast<std::chrono::seconds>(timestamp)
                .count());
        record.event.oemCD.recordType = recordType;
        // The ManufactureID and OEM Defined are packed in the sensor data
        // Fill the 9 bytes of Manufacture ID and oemDefined
        memcpy(&record.event.oemCD.manufacturerID, sensorData.data(),
               std::min(sensorData.size(), static_cast<size_t>(9)));
    }
    else if (recordType >= 0xE0)
    {
        record.event.oemEF.recordType = recordType;
        // The remaining 13 bytes are the OEM Defined data
        memcpy(&record.event.oemEF.oemDefined, sensorData.data(),
               std::min(sensorData.size(), static_cast<size_t>(13)));
    }
}

GetSELEntryResponse
    prepareSELEntry(const std::string& objPath,
                    ipmi::sensor::InvObjectIDMap::const_iterator iter)
{
    GetSELEntryResponse record{};

    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
    auto service = ipmi::getService(bus, logEntryIntf, objPath);

    // Read all the log entry properties.
    auto methodCall = bus.new_method_call(service.c_str(), objPath.c_str(),
                                          propIntf, "GetAll");
    methodCall.append(logEntryIntf);

    auto reply = bus.call(methodCall);
    if (reply.is_method_error())
    {
        log<level::ERR>("Error in reading logging property entries");
        elog<InternalFailure>();
    }

    std::map<PropertyName, PropertyType> entryData;
    reply.read(entryData);

    // Read Id from the log entry.
    static constexpr auto propId = "Id";
    auto iterId = entryData.find(propId);
    if (iterId == entryData.end())
    {
        log<level::ERR>("Error in reading Id of logging entry");
        elog<InternalFailure>();
    }

    // Read Timestamp from the log entry.
    static constexpr auto propTimeStamp = "Timestamp";
    auto iterTimeStamp = entryData.find(propTimeStamp);
    if (iterTimeStamp == entryData.end())
    {
        log<level::ERR>("Error in reading Timestamp of logging entry");
        elog<InternalFailure>();
    }
    std::chrono::milliseconds chronoTimeStamp(
        std::get<uint64_t>(iterTimeStamp->second));

    if (iter == invSensors.end())
    {
        // It is expected to be a custom SEL entry
        record.event.oemCD.recordID =
            static_cast<uint16_t>(std::get<uint32_t>(iterId->second));
        iterId = entryData.find(propAdditionalData);
        if (iterId == entryData.end())
        {
            log<level::ERR>("Error finding AdditionalData");
            elog<InternalFailure>();
        }
        const auto& addData = std::get<AdditionalData>(iterId->second);
        auto m = parseAdditionalData(addData);
        auto recordType = convert(m[strRecordType]);
        auto isOEM = isRecordOEM(recordType);
        if (isOEM)
        {
            constructOEMSel(recordType, chronoTimeStamp, m, record);
        }
        else
        {
            // TODO
        }
    }
    else
    {

        record.event.eventRecord.recordID =
            static_cast<uint16_t>(std::get<uint32_t>(iterId->second));
        record.event.eventRecord.timeStamp = static_cast<uint32_t>(
            std::chrono::duration_cast<std::chrono::seconds>(chronoTimeStamp)
                .count());

        static constexpr auto generatorID = 0x2000;
        static constexpr auto eventMsgRevision = 0x04;

        record.event.eventRecord.recordType = systemEventRecord;
        record.event.eventRecord.generatorID = generatorID;
        record.event.eventRecord.eventMsgRevision = eventMsgRevision;

        record.event.eventRecord.sensorType = iter->second.sensorType;
        record.event.eventRecord.sensorNum = iter->second.sensorID;
        record.event.eventRecord.eventData1 = iter->second.eventOffset;

        // Read Resolved from the log entry.
        static constexpr auto propResolved = "Resolved";
        auto iterResolved = entryData.find(propResolved);
        if (iterResolved == entryData.end())
        {
            log<level::ERR>("Error in reading Resolved field of logging entry");
            elog<InternalFailure>();
        }

        static constexpr auto deassertEvent = 0x80;

        // Evaluate if the event is assertion or deassertion event
        if (std::get<bool>(iterResolved->second))
        {
            record.event.eventRecord.eventType =
                deassertEvent | iter->second.eventReadingType;
        }
        else
        {
            record.event.eventRecord.eventType = iter->second.eventReadingType;
        }
    }

    return record;
}

} // namespace internal

GetSELEntryResponse convertLogEntrytoSEL(const std::string& objPath)
{
    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};

    static constexpr auto assocIntf =
        "xyz.openbmc_project.Association.Definitions";
    static constexpr auto assocProp = "Associations";

    auto service = ipmi::getService(bus, assocIntf, objPath);

    // Read the Associations interface.
    auto methodCall =
        bus.new_method_call(service.c_str(), objPath.c_str(), propIntf, "Get");
    methodCall.append(assocIntf);
    methodCall.append(assocProp);

    auto reply = bus.call(methodCall);
    if (reply.is_method_error())
    {
        log<level::ERR>("Error in reading Associations interface");
        elog<InternalFailure>();
    }

    using AssociationList =
        std::vector<std::tuple<std::string, std::string, std::string>>;

    std::variant<AssociationList> list;
    reply.read(list);

    auto& assocs = std::get<AssociationList>(list);

    /*
     * Check if the log entry has any callout associations, if there is a
     * callout association try to match the inventory path to the corresponding
     * IPMI sensor.
     */
    for (const auto& item : assocs)
    {
        if (std::get<0>(item).compare(CALLOUT_FWD_ASSOCIATION) == 0)
        {
            auto iter = invSensors.find(std::get<2>(item));
            if (iter == invSensors.end())
            {
                iter = invSensors.find(BOARD_SENSOR);
                if (iter == invSensors.end())
                {
                    log<level::ERR>("Motherboard sensor not found");
                    elog<InternalFailure>();
                }
            }

            return internal::prepareSELEntry(objPath, iter);
        }
    }

    // If there are no callout associations link the log entry to system event
    // sensor
    auto iter = invSensors.find(SYSTEM_SENSOR);
    return internal::prepareSELEntry(objPath, iter);
}

std::chrono::seconds getEntryTimeStamp(const std::string& objPath)
{
    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};

    auto service = ipmi::getService(bus, logEntryIntf, objPath);

    using namespace std::string_literals;
    static const auto propTimeStamp = "Timestamp"s;

    auto methodCall =
        bus.new_method_call(service.c_str(), objPath.c_str(), propIntf, "Get");
    methodCall.append(logEntryIntf);
    methodCall.append(propTimeStamp);

    auto reply = bus.call(methodCall);
    if (reply.is_method_error())
    {
        log<level::ERR>("Error in reading Timestamp from Entry interface");
        elog<InternalFailure>();
    }

    std::variant<uint64_t> timeStamp;
    reply.read(timeStamp);

    std::chrono::milliseconds chronoTimeStamp(std::get<uint64_t>(timeStamp));

    return std::chrono::duration_cast<std::chrono::seconds>(chronoTimeStamp);
}

void readLoggingObjectPaths(ObjectPaths& paths)
{
    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
    auto depth = 0;
    paths.clear();

    auto mapperCall = bus.new_method_call(mapperBusName, mapperObjPath,
                                          mapperIntf, "GetSubTreePaths");
    mapperCall.append(logBasePath);
    mapperCall.append(depth);
    mapperCall.append(ObjectPaths({logEntryIntf}));

    auto reply = bus.call(mapperCall);
    if (reply.is_method_error())
    {
        log<level::INFO>("Error in reading logging entry object paths");
    }
    else
    {
        reply.read(paths);

        std::sort(paths.begin(), paths.end(),
                  [](const std::string& a, const std::string& b) {
                      namespace fs = std::filesystem;
                      fs::path pathA(a);
                      fs::path pathB(b);
                      auto idA = std::stoul(pathA.filename().string());
                      auto idB = std::stoul(pathB.filename().string());

                      return idA < idB;
                  });
    }
}

} // namespace sel

} // namespace ipmi
<|endoftext|>


<commit_before>#include "seqMachine.h"

seqMachine::seqMachine()
{
    /*
    num_iters_ = num_iters;
    num_passes_ = num_passes;
    budget_ = budget;
    */
}

void seqMachine::construct_envs_items(vw*model, istream &fin)
{
    int id, numItems;
    //   char str[100];
    string str;
    envs.clear();
    int ct = 0;
    while (!fin.eof())
	{
	    //assume each environment starts with id,numItems
	    /*
	    getline(fin, str, '\n');
	    if (fin.eof())
		break;
	    sscanf(str.c_str(), "%d %d", &id, &numItems);
	    cout << id <<" " << numItems <<endl;
	    */
	    environment env;
	    cout << "read_from_stream for EnvId " << ct <<endl;
	    env.read_from_stream(model, fin);

	    //  env.read_from_stream(model, fin, numItems);
	    envs.push_back(env);
	    // cout << "numItems " << envs[ct].get_numItems() <<endl;
	    ct++;
	}
}

void seqMachine::scp_train(vw*model, submodOracle & fOracle, string fileName)
{

    //initialize with greedy on each environment
    cout <<"start SCP_TRAIN by Greedy Coaching" <<endl;
    vector<int> randIndex;
    ifstream fin;
    fin.open(fileName.c_str());
    //    construct_envs_items(model, fin);
    envs.clear();
    int ct = 0;
    while (!fin.eof())
	{
	    environment env;
	    //  cout << "read_from_stream for EnvId " << ct <<endl;
	    env.read_from_stream(model, fin);
	    env.setBudget(budget_);
	    env.setAlgoType(algo_);
	    envs.push_back(env);
	    //   cout << "numItems " << envs[ct].get_numItems() <<endl;
	    //  envs[ct].multiRoundTrain(model, fOracle, true, num_passes_);
	    ct++;
	}
    //test whether can back up one copy of all enviroments
    randIndex = generate_random_index(envs.size());
    for (int i = 0; i< envs.size(); i++)
	{
   	    envs[randIndex[i]].multiRoundTrain(model, fOracle, true, num_passes_);
	}
    fin.close();
    cout << "greedy coaching finished" <<endl;
    for (int iter = 1; iter < num_iters_; iter++)
	{
	    cout << "iterations " << iter << endl;
	    envs.clear();
	    ct = 0;
	    fin.open(fileName.c_str());
	    while (!fin.eof())
		{
		    environment env;
		    // cout << "read_from_stream for EnvId " << ct <<endl;
		    env.read_from_stream(model, fin);
		    env.setBudget(budget_);
		    env.setAlgoType(algo_);
		    envs.push_back(env);
		    //  cout << "numItems " << envs[ct].get_numItems() <<endl;
		    //   envs[ct].multiRoundTrain(model, fOracle, false, num_passes_);
		    ct++;
		}

	    randIndex = generate_random_index(envs.size());
	    for (int i = 0; i< envs.size(); i++)
		{
		    envs[randIndex[i]].multiRoundTrain(model, fOracle, false, num_passes_);
		}

	    fin.close();
	}
    cout << "training completed" << endl;
}

void seqMachine::scp_predict(vw* model, string fileName)
{
    cout << "Run SCP_Predict Only" <<endl;
    ifstream fin;
    fin.open(fileName.c_str());
    //    construct_envs_items(model, fin);
    // for (int i = 0; i < envs.size(); i++)
    int ct = 0;
    envs.clear();
    while (!fin.eof())
	{
	    environment env;
	    //	    cout << "read_from_stream for EnvId " << ct <<endl;
	    env.read_from_stream(model, fin);
	    env.setBudget(budget_);
	    envs.push_back(env);
	    //	    cout << "numItems " << envs[ct].get_numItems() <<endl;
	    envs[ct].multiRoundPredictOnly(model);
	    ct++;
	}
    fin.close();
}

void seqMachine::check_predict_score (submodOracle & fOracle)
{
    double avgFinalScore;
    for (int i = 0; i < envs.size(); i++)
	{
	    cout << "For Environment " << i <<endl;
	    vector<double> score = envs[i].getPerSlotScore(fOracle);
	    avgFinalScore += score[score.size() - 1];
	}
    avgFinalScore /= envs.size();
    cout << "Average Prediction Final Score " << avgFinalScore << endl;
}

vector<int> seqMachine::generate_random_index(int tot)
{
    vector<int> randIndex;
    for (int i = 0; i < tot; i++ )
	randIndex.push_back(i);
    std::random_shuffle(randIndex.begin(), randIndex.end());
    for (int i = 0; i < randIndex.size(); i++)
	{
	    cout << randIndex[i] << ",";
	}
    cout << endl;
    return randIndex;
}
<commit_msg>Delete seqMachine.cpp<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2017 Sony Corporation. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <nbla/array_registry.hpp>
#include <nbla/context.hpp>
#include <nbla/synced_array.hpp>

namespace nbla {
// Constructor
SyncedArray::SyncedArray(const Size_t size)
    : head_{"", "", dtypes::FLOAT}, zeroing_(false), filling_(false),
      modification_count_(0) {
  size_ = size;
}

SyncedArray::~SyncedArray() {}

Array *SyncedArray::cast(dtypes dtype, const Context &ctx, bool write_only) {
  return cast_sp(dtype, ctx, write_only).get();
}

shared_ptr<Array> SyncedArray::cast_sp(dtypes dtype, const Context &ctx,
                                       bool write_only) {
  // 1. Create an array and/or synchronize with the head.
  head_ = sync(dtype, ctx, write_only); // cast() changes head.
  // 2. Clear all previous arrays.
  auto created_array = array_[head_.key];
  clear_all_array();
  created_array.second = true;
  array_[head_.key] = created_array;
  // 3. Increment modification count to let solver to know whether it's modified
  // or not
  modification_count_++;
  // 4. Return a requested array
  return created_array.first;
}

const Array *SyncedArray::get(dtypes dtype, const Context &ctx) {
  ArrayDesc desc = sync(dtype, ctx); // get() does not change head.
  array_[desc.key].second = true;    // Set as at-head.
  return array_[desc.key].first.get();
}

void SyncedArray::zero() {
  clear_all_array();
  zeroing_ = true;
  modification_count_++;
}

void SyncedArray::fill(float value) {
  clear_all_array();
  filling_ = true;
  fill_value_ = value;
  modification_count_++;
}

size_t SyncedArray::modification_count() const { return modification_count_; }

SyncedArray::ArrayDesc SyncedArray::sync(dtypes dtype, const Context &ctx_orig,
                                         bool write_only) {
  Context ctx = ArrayCreator::filter_context(ctx_orig);
  ArrayDesc desc{get_array_key_from_context(ctx) + ":" + dtype_to_string(dtype),
                 ctx.array_class, dtype};
  // Specified array is not allocated
  if (array_.find(desc.key) == array_.end()) {
    if (array_.size() == 0)
      head_ = desc;
    array_[desc.key] = std::make_pair(
        shared_ptr<Array>(ArrayCreator::create(size_, dtype, ctx)), false);
  }
  if (write_only) {
    return desc;
  }

  auto ah = array_[desc.key];
  Array *array = ah.first.get();
  bool at_head = ah.second;
  // Not initialized or the array is not at head.
  if (at_head) {
    return desc;
  }
  if (zeroing_) {
    // Do lazy evaluation of zero().
    array->zero();
  } else if (filling_) {
    // Do lazy evaluation of fill().
    array->fill(fill_value_);
  } else if (array_.size() > 1) {
    // TODO: Better heuristic choice from current heads
    Array *head_array = array_[head_.key].first.get();
    if (head_.array_class == desc.array_class) {
      array->copy_from(head_array);
    } else {
      ArraySynchronizer::synchronize(head_.array_class, head_array,
                                     desc.array_class, array);
    }
  }
  return desc;
}

void SyncedArray::clear() {
  array_.clear();
  zeroing_ = false;
  filling_ = false;
}

// Reset head state
void SyncedArray::clear_all_array() {
  array_.clear();
  zeroing_ = false;
  filling_ = false;
}
}
<commit_msg>[c++] debug message of array synchronizer<commit_after>// Copyright (c) 2017 Sony Corporation. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <nbla/array_registry.hpp>
#include <nbla/context.hpp>
#include <nbla/synced_array.hpp>

#ifdef ENABLE_SYNC_DEBUG
#include <cstdlib>
static bool sync_debug_enabled() {
  static bool enabled = false;
  if (enabled) {
    return enabled;
  }
  const char *env_c = std::getenv("NNABLA_SYNC_DEBUG");
  if (env_c == nullptr) {
    return true;
  }
  std::string env = std::string(env_c);
  try {
    if (std::stoi(env) == 0) {
      return false;
    }
  } catch (...) {
  }
  enabled = true;
  return true;
}

#define SYNC_DEBUG(...)                                                        \
  if (sync_debug_enabled()) {                                                  \
    printf(__VA_ARGS__);                                                       \
    printf("\n");                                                              \
  }
#else
#define SYNC_DEBUG(...)
#endif

namespace nbla {
// Constructor
SyncedArray::SyncedArray(const Size_t size)
    : head_{"", "", dtypes::FLOAT}, zeroing_(false), filling_(false),
      modification_count_(0) {
  size_ = size;
}

SyncedArray::~SyncedArray() {}

Array *SyncedArray::cast(dtypes dtype, const Context &ctx, bool write_only) {
  return cast_sp(dtype, ctx, write_only).get();
}

shared_ptr<Array> SyncedArray::cast_sp(dtypes dtype, const Context &ctx,
                                       bool write_only) {
  // 1. Create an array and/or synchronize with the head.
  head_ = sync(dtype, ctx, write_only); // cast() changes head.
  // 2. Clear all previous arrays.
  auto created_array = array_[head_.key];
  clear_all_array();
  created_array.second = true;
  array_[head_.key] = created_array;
  // 3. Increment modification count to let solver to know whether it's modified
  // or not
  modification_count_++;
  // 4. Return a requested array
  return created_array.first;
}

const Array *SyncedArray::get(dtypes dtype, const Context &ctx) {
  ArrayDesc desc = sync(dtype, ctx); // get() does not change head.
  array_[desc.key].second = true;    // Set as at-head.
  return array_[desc.key].first.get();
}

void SyncedArray::zero() {
  clear_all_array();
  zeroing_ = true;
  modification_count_++;
}

void SyncedArray::fill(float value) {
  clear_all_array();
  filling_ = true;
  fill_value_ = value;
  modification_count_++;
}

size_t SyncedArray::modification_count() const { return modification_count_; }

SyncedArray::ArrayDesc SyncedArray::sync(dtypes dtype, const Context &ctx_orig,
                                         bool write_only) {
  Context ctx = ArrayCreator::filter_context(ctx_orig);
  ArrayDesc desc{get_array_key_from_context(ctx) + ":" + dtype_to_string(dtype),
                 ctx.array_class, dtype};
  // Specified array is not allocated
  if (array_.find(desc.key) == array_.end()) {
    if (array_.size() == 0)
      head_ = desc;
    array_[desc.key] = std::make_pair(
        shared_ptr<Array>(ArrayCreator::create(size_, dtype, ctx)), false);
  }
  if (write_only) {
    return desc;
  }

  auto ah = array_[desc.key];
  Array *array = ah.first.get();
  bool at_head = ah.second;
  // Not initialized or the array is not at head.
  if (at_head) {
    return desc;
  }
  if (zeroing_) {
    // Do lazy evaluation of zero().
    array->zero();
  } else if (filling_) {
    // Do lazy evaluation of fill().
    array->fill(fill_value_);
  } else if (array_.size() > 1) {
    // TODO: Better heuristic choice from current heads
    Array *head_array = array_[head_.key].first.get();
    if (head_.array_class == desc.array_class) {
      array->copy_from(head_array);
    } else {
      ArraySynchronizer::synchronize(head_.array_class, head_array,
                                     desc.array_class, array);
      SYNC_DEBUG("SYNC: %s<%s> --[%ld elements (%ld bytes in %s)]--> %s<%s>.",
                 head_.array_class.c_str(),
                 dtype_to_string(head_.dtype).c_str(),
                 size() / sizeof_dtype(head_.dtype), size(),
                 dtype_to_string(head_.dtype).c_str(), desc.array_class.c_str(),
                 dtype_to_string(desc.dtype).c_str());
    }
  }
  return desc;
}

void SyncedArray::clear() {
  array_.clear();
  zeroing_ = false;
  filling_ = false;
}

// Reset head state
void SyncedArray::clear_all_array() {
  array_.clear();
  zeroing_ = false;
  filling_ = false;
}
}
<|endoftext|>


<commit_before>#include <uqEnvironment.h>
#include <uqStatisticalInverseProblem.h>

int main(int argc, char **argv)
{
  int num_times = 40;
  double obs_var = 1e-2;
  double burger_speed = 1.0;
  double dt = 0.01;

  MPI_Init(&argc, &argv);

  // Set up the environment
  uqFullEnvironmentClass *env = new uqFullEnvironmentClass(MPI_COMM_WORLD,
      "my_input_file.in", "", NULL);

  // Set up the prior -- only Gaussians are supported for now
  // A gaussian prior is specified by a mean function and a covariance operator

  // Mean function
  FUNCTION *mu = new FUNCTION(something here);
  // Maybe the default constructor should default to the zero function?

  // Inverse covariance operator: e.g., the inverse laplacian
  OPERATOR *C = new OPERATOR("Laplacian");

  // Set up the Gaussian measure. s is the power that determines regularity > 0
  uqGaussianRF *prior = new GAUSSIAN_MEASURE(mu, C, s);

  // Set up the likelihood. It takes a field
  Likelihood *likelihood = new Likelihood(*env, true_initial_condition,
      burger_speed, num_times, dt, obs_var);
  likelihood->synthesize_data();

  // Set up the inverse problem
  uqSipOptionsValuesClass opts;
  uqStatisticalInverseProblemClass *ip = new
    uqStatisticalInverseProblemClass("", &opts, *prior, *likelihood);

  // MCMC seed
  FUNCTION initialVals();  // Zero as the MCMC seed
  ip->solveWithBayesMetropolisHastings (NULL, initialVals);

  delete env;
  delete mu;
  delete C;
  delete prior;
  delete likelihood;
  MPI_Finalize();

  return 0;
}
<commit_msg>[queso]: Make function and operators concrete<commit_after>#include <uqLibMeshFunction.h>
#include <uqLaplacianOperator.h>
#include <uqEnvironment.h>
#include <uqStatisticalInverseProblem.h>

int main(int argc, char **argv)
{
  int num_times = 40;
  double obs_var = 1e-2;
  double burger_speed = 1.0;
  double dt = 0.01;

  MPI_Init(&argc, &argv);

  // Set up the environment
  uqFullEnvironmentClass *env = new uqFullEnvironmentClass(MPI_COMM_WORLD,
      "my_input_file.in", "", NULL);

  // Set up the prior -- only Gaussians are supported for now
  // A gaussian prior is specified by a mean function and a covariance operator

  // Mean function
  uqLibMeshFunction *mu = new uqLibMeshFunction();
  // Maybe the default constructor should default to the zero function?

  // Inverse covariance operator: e.g., the inverse laplacian to the 3
  uqNegativeLaplacianOperator *C = new uqNegativeLaplacianOperator(-3.0);

  // Set up the Gaussian measure.
  uqGaussianRF *prior = new GAUSSIAN_MEASURE(mu, C);

  // Set up the likelihood. It takes a field
  Likelihood *likelihood = new Likelihood(*env, true_initial_condition,
      burger_speed, num_times, dt, obs_var);
  likelihood->synthesize_data();

  // Set up the inverse problem
  uqSipOptionsValuesClass opts;
  uqStatisticalInverseProblemClass *ip = new
    uqStatisticalInverseProblemClass("", &opts, *prior, *likelihood);

  // MCMC seed
  uqLibMeshFunction initialVals();  // Zero as the MCMC seed
  ip->solveWithBayesMetropolisHastings (NULL, initialVals);

  delete env;
  delete mu;
  delete C;
  delete prior;
  delete likelihood;
  MPI_Finalize();

  return 0;
}
<|endoftext|>


<commit_before>#include <coffee/graphics/common/query/gpu_query.h>
#include <coffee/core/string_casting.h>
#include <coffee/core/types/cdef/infotypes.h>
#include <nvml.h>

namespace Coffee{
namespace GpuInfo{

/* Helper functions */
STATICINLINE void error_print(nvmlReturn_t code)
{
    if(code != NVML_SUCCESS)
        fprintf(stderr, "NVIDIA ML error: %s\n", nvmlErrorString(code));
}

nvmlDevice_t device(gpucount_t i)
{
    nvmlDevice_t dev;
    auto r = nvmlDeviceGetHandleByIndex_v2(i, &dev);
    error_print(r);
    return dev;
}

/* Implementation functions */
SWVersionInfo GetDriver()
{
    CString driver_ver;
    driver_ver.resize(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE);

    nvmlSystemGetDriverVersion(&driver_ver[0], NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE);

    driver_ver.resize(driver_ver.find('\0'));

    CString major = driver_ver.substr(0, driver_ver.find('.'));
    CString minor = driver_ver.substr(driver_ver.find('.')+1, driver_ver.length());

    return SWVersionInfo("NVIDIA",
                         Mem::Convert::strtouint(major.c_str()),
                         Mem::Convert::strtouint(minor.c_str()));
}

gpucount_t GetNumGpus()
{
    uint32 c = 0;
    nvmlDeviceGetCount(&c);
    return c;
}

HWDeviceInfo GetModel(gpucount_t i)
{
    auto dev = device(i);

    CString name;
    name.resize(NVML_DEVICE_NAME_BUFFER_SIZE);
    auto r = nvmlDeviceGetName(dev, &name[0], C_CAST<uint32>(name.size()));
    error_print(r);

    CString bios;
    bios.resize(NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE);
    r = nvmlDeviceGetVbiosVersion(dev, &bios[0], C_CAST<uint32>(bios.size()));
    error_print(r);

    return HWDeviceInfo("NVIDIA", &name[0], &bios[0]);
}

MemStatus GetMemInfo(gpucount_t i)
{
    auto dev = device(i);

    nvmlMemory_t mem = {};
    auto r = nvmlDeviceGetMemoryInfo(dev, &mem);
    error_print(r);

    return {mem.total, mem.used, mem.free};
}

uint64 GetProcMemInfo(gpucount_t i, proc_t pid)
{
    auto dev = device(i);

    uint32 count = 0;
    nvmlDeviceGetGraphicsRunningProcesses(dev, &count, nullptr);

    Vector<nvmlProcessInfo_t> procs;
    procs.resize(count);
    auto r = nvmlDeviceGetGraphicsRunningProcesses(dev, &count, procs.data());
    error_print(r);

    for(nvmlProcessInfo_t const& p : procs)
        if(p.pid == pid)
            return p.usedGpuMemory;

    return 0;
}

TempRange GetTemp(gpucount_t i)
{
    auto dev = device(i);

    uint32 current = 0;
    uint32 max = 0;

    auto r = nvmlDeviceGetTemperature(dev, NVML_TEMPERATURE_GPU, &current);
    error_print(r);

    r = nvmlDeviceGetTemperatureThreshold(dev, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN, &max);
    error_print(r);

    return {C_CAST<scalar>(current), C_CAST<scalar>(max)};
}

ClockRange GetClock(gpucount_t i, Clock clk)
{
    auto dev = device(i);

    nvmlClockType_t type = NVML_CLOCK_COUNT;

    switch(clk)
    {
    case Clock::Graphics:
        type = NVML_CLOCK_GRAPHICS;
        break;
    case Clock::Memory:
        type = NVML_CLOCK_MEM;
        break;
    default:
        break;
    }

    if(type == NVML_CLOCK_COUNT)
        return {0, 0, 0};

    uint32 curr = 0, min = 0, max = 0;
    auto r = nvmlDeviceGetApplicationsClock(dev, type, &curr);
    error_print(r);
    r = nvmlDeviceGetClockInfo(dev, type, &min);
    error_print(r);
    r = nvmlDeviceGetMaxClockInfo(dev, type, &max);
    error_print(r);

    return {curr, min, max};
}

PMode GetPowerMode(gpucount_t i)
{
    auto dev = device(i);

    nvmlPstates_t pstate = {};
    auto r = nvmlDeviceGetPerformanceState(dev, &pstate);
    error_print(r);

    return (pstate > NVML_PSTATE_1)
            ? PMode::Performance
            : PMode::Powersave;
}

UsageMeter GetUsage(gpucount_t i)
{
    auto dev = device(i);

    nvmlUtilization_t util = {};
    auto r = nvmlDeviceGetUtilizationRates(dev, &util);
    error_print(r);
    uint32 decoder = 0, encoder = 0, sampling = 0;
    r = nvmlDeviceGetDecoderUtilization(dev, &decoder, &sampling);
    error_print(r);
    r = nvmlDeviceGetDecoderUtilization(dev, &encoder, &sampling);
    error_print(r);

    return {C_CAST<uint8>(util.memory), C_CAST<uint8>(util.gpu),
                C_CAST<uint8>(decoder), C_CAST<uint8>(encoder)};
}

TransferStatus GetPcieTransfer(gpucount_t i)
{
    auto dev = device(i);

    TransferStatus stat = {};
    auto r = nvmlDeviceGetPcieThroughput(dev, NVML_PCIE_UTIL_RX_BYTES, &stat.rx);
    r = nvmlDeviceGetPcieThroughput(dev, NVML_PCIE_UTIL_TX_BYTES, &stat.tx);

    return stat;
}

GpuQueryInterface GetNvidia()
{
    return {
        GetDriver,
                GetNumGpus,
                GetModel,
                GetMemInfo,
                GetProcMemInfo,
                GetTemp,
                GetClock,
                GetPowerMode,
                GetUsage,
                GetPcieTransfer,
    };
}

}
}

extern "C" GpuQueryFunction* GetGpuQuery();

GpuQueryFunction* GetGpuQuery()
{
    if(nvmlInit() == NVML_SUCCESS && Coffee::GpuInfo::GetNumGpus())
    {
        return new GpuQueryFunction { Coffee::GpuInfo::GetNvidia };
    }
    //        fprintf(stderr, "NVML could not be initialized\n");
    return nullptr;
}
<commit_msg> - Add fix for NvidiaML code in case it runs into GDK 6.x<commit_after>#include <coffee/graphics/common/query/gpu_query.h>
#include <coffee/core/string_casting.h>
#include <coffee/core/types/cdef/infotypes.h>
#include <nvml.h>

namespace Coffee{
namespace GpuInfo{

/* Helper functions */
STATICINLINE void error_print(nvmlReturn_t code)
{
    if(code != NVML_SUCCESS)
        fprintf(stderr, "NVIDIA ML error: %s\n", nvmlErrorString(code));
}

nvmlDevice_t device(gpucount_t i)
{
    nvmlDevice_t dev;
    auto r = nvmlDeviceGetHandleByIndex_v2(i, &dev);
    error_print(r);
    return dev;
}

/* Implementation functions */
SWVersionInfo GetDriver()
{
    CString driver_ver;
    driver_ver.resize(NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE);

    nvmlSystemGetDriverVersion(&driver_ver[0], NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE);

    driver_ver.resize(driver_ver.find('\0'));

    CString major = driver_ver.substr(0, driver_ver.find('.'));
    CString minor = driver_ver.substr(driver_ver.find('.')+1, driver_ver.length());

    return SWVersionInfo("NVIDIA",
                         Mem::Convert::strtouint(major.c_str()),
                         Mem::Convert::strtouint(minor.c_str()));
}

gpucount_t GetNumGpus()
{
    uint32 c = 0;
    nvmlDeviceGetCount(&c);
    return c;
}

HWDeviceInfo GetModel(gpucount_t i)
{
    auto dev = device(i);

    CString name;
    name.resize(NVML_DEVICE_NAME_BUFFER_SIZE);
    auto r = nvmlDeviceGetName(dev, &name[0], C_CAST<uint32>(name.size()));
    error_print(r);

    CString bios;
    bios.resize(NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE);
    r = nvmlDeviceGetVbiosVersion(dev, &bios[0], C_CAST<uint32>(bios.size()));
    error_print(r);

    return HWDeviceInfo("NVIDIA", &name[0], &bios[0]);
}

MemStatus GetMemInfo(gpucount_t i)
{
    auto dev = device(i);

    nvmlMemory_t mem = {};
    auto r = nvmlDeviceGetMemoryInfo(dev, &mem);
    error_print(r);

    return {mem.total, mem.used, mem.free};
}

uint64 GetProcMemInfo(gpucount_t i, proc_t pid)
{
#if NVML_API_VERSION >= 7
    auto dev = device(i);

    uint32 count = 0;
    nvmlDeviceGetGraphicsRunningProcesses(dev, &count, nullptr);

    Vector<nvmlProcessInfo_t> procs;
    procs.resize(count);
    auto r = nvmlDeviceGetGraphicsRunningProcesses(dev, &count, procs.data());
    error_print(r);

    for(nvmlProcessInfo_t const& p : procs)
        if(p.pid == pid)
            return p.usedGpuMemory;
#endif
    return 0;
}

TempRange GetTemp(gpucount_t i)
{
    auto dev = device(i);

    uint32 current = 0;
    uint32 max = 0;

    auto r = nvmlDeviceGetTemperature(dev, NVML_TEMPERATURE_GPU, &current);
    error_print(r);

    r = nvmlDeviceGetTemperatureThreshold(dev, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN, &max);
    error_print(r);

    return {C_CAST<scalar>(current), C_CAST<scalar>(max)};
}

ClockRange GetClock(gpucount_t i, Clock clk)
{
    auto dev = device(i);

    nvmlClockType_t type = NVML_CLOCK_COUNT;

    switch(clk)
    {
    case Clock::Graphics:
        type = NVML_CLOCK_GRAPHICS;
        break;
    case Clock::Memory:
        type = NVML_CLOCK_MEM;
        break;
    default:
        break;
    }

    if(type == NVML_CLOCK_COUNT)
        return {0, 0, 0};

    uint32 curr = 0, min = 0, max = 0;
    auto r = nvmlDeviceGetApplicationsClock(dev, type, &curr);
    error_print(r);
    r = nvmlDeviceGetClockInfo(dev, type, &min);
    error_print(r);
    r = nvmlDeviceGetMaxClockInfo(dev, type, &max);
    error_print(r);

    return {curr, min, max};
}

PMode GetPowerMode(gpucount_t i)
{
    auto dev = device(i);

    nvmlPstates_t pstate = {};
    auto r = nvmlDeviceGetPerformanceState(dev, &pstate);
    error_print(r);

    return (pstate > NVML_PSTATE_1)
            ? PMode::Performance
            : PMode::Powersave;
}

UsageMeter GetUsage(gpucount_t i)
{
    auto dev = device(i);

    nvmlUtilization_t util = {};
    auto r = nvmlDeviceGetUtilizationRates(dev, &util);
    error_print(r);
    uint32 decoder = 0, encoder = 0, sampling = 0;
    r = nvmlDeviceGetDecoderUtilization(dev, &decoder, &sampling);
    error_print(r);
    r = nvmlDeviceGetDecoderUtilization(dev, &encoder, &sampling);
    error_print(r);

    return {C_CAST<uint8>(util.memory), C_CAST<uint8>(util.gpu),
                C_CAST<uint8>(decoder), C_CAST<uint8>(encoder)};
}

TransferStatus GetPcieTransfer(gpucount_t i)
{
#if NVML_API_VERSION >= 7
    auto dev = device(i);

    TransferStatus stat = {};
    auto r = nvmlDeviceGetPcieThroughput(dev, NVML_PCIE_UTIL_RX_BYTES, &stat.rx);
    r = nvmlDeviceGetPcieThroughput(dev, NVML_PCIE_UTIL_TX_BYTES, &stat.tx);

    return stat;
#else
    return {};
#endif
}

GpuQueryInterface GetNvidia()
{
    return {
        GetDriver,
                GetNumGpus,
                GetModel,
                GetMemInfo,
                GetProcMemInfo,
                GetTemp,
                GetClock,
                GetPowerMode,
                GetUsage,
                GetPcieTransfer,
    };
}

}
}

extern "C" GpuQueryFunction* GetGpuQuery();

GpuQueryFunction* GetGpuQuery()
{
    if(nvmlInit() == NVML_SUCCESS && Coffee::GpuInfo::GetNumGpus())
    {
        return new GpuQueryFunction { Coffee::GpuInfo::GetNvidia };
    }
    //        fprintf(stderr, "NVML could not be initialized\n");
    return nullptr;
}
<|endoftext|>


<commit_before>// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/core/ext/transport/binder/server/binder_server.h"

#include <memory>
#include <thread>
#include <vector>

#include <gtest/gtest.h>

#include "absl/memory/memory.h"

#include <grpcpp/grpcpp.h>
#include <grpcpp/impl/grpc_library.h>
#include <grpcpp/security/binder_credentials.h>
#include <grpcpp/security/binder_security_policy.h>

#include "src/core/ext/transport/binder/client/channel_create_impl.h"
#include "src/core/ext/transport/binder/server/binder_server.h"
#include "test/core/transport/binder/end2end/fake_binder.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"

namespace grpc {
namespace testing {

namespace {

class BinderServerCredentialsImpl final : public ServerCredentials {
 public:
  int AddPortToServer(const std::string& addr, grpc_server* server) override {
    return grpc_core::AddBinderPort(
        addr, server,
        [](grpc_binder::TransactionReceiver::OnTransactCb transact_cb) {
          return absl::make_unique<
              grpc_binder::end2end_testing::FakeTransactionReceiver>(
              nullptr, std::move(transact_cb));
        },
        std::make_shared<
            grpc::experimental::binder::UntrustedSecurityPolicy>());
  }

  void SetAuthMetadataProcessor(
      const std::shared_ptr<AuthMetadataProcessor>& /*processor*/) override {
    GPR_ASSERT(false);
  }

 private:
  bool IsInsecure() const override { return true; }
};

}  // namespace

std::shared_ptr<ServerCredentials> BinderServerCredentials() {
  return std::shared_ptr<ServerCredentials>(new BinderServerCredentialsImpl());
}

std::shared_ptr<grpc::Channel> CreateBinderChannel(
    std::unique_ptr<grpc_binder::Binder> endpoint_binder) {
  grpc::internal::GrpcLibrary init_lib;
  init_lib.init();

  return grpc::CreateChannelInternal(
      "",
      grpc::internal::CreateDirectBinderChannelImplForTesting(
          std::move(endpoint_binder), nullptr,
          std::make_shared<
              grpc::experimental::binder::UntrustedSecurityPolicy>()),
      std::vector<std::unique_ptr<
          grpc::experimental::ClientInterceptorFactoryInterface>>());
}

}  // namespace testing
}  // namespace grpc

namespace {

class BinderServerTest : public ::testing::Test {
 public:
  BinderServerTest() {
    grpc_binder::end2end_testing::g_transaction_processor =
        new grpc_binder::end2end_testing::TransactionProcessor();
  }
  ~BinderServerTest() override {
    delete grpc_binder::end2end_testing::g_transaction_processor;
  }
  static void SetUpTestSuite() { grpc_init(); }
  static void TearDownTestSuite() { grpc_shutdown(); }
};

#ifndef GPR_SUPPORT_BINDER_TRANSPORT
TEST(BinderServerCredentialsTest,
     FailedInEnvironmentsNotSupportingBinderTransport) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort(
      "binder:fail",
      grpc::experimental::BinderServerCredentials(
          std::make_shared<
              grpc::experimental::binder::UntrustedSecurityPolicy>()));
  EXPECT_EQ(server_builder.BuildAndStart(), nullptr);
}
#endif  // !GPR_SUPPORT_BINDER_TRANSPORT

TEST_F(BinderServerTest, BuildAndStart) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  EXPECT_NE(grpc::experimental::binder::GetEndpointBinder("example.service"),
            nullptr);
  server->Shutdown();
  EXPECT_EQ(grpc::experimental::binder::GetEndpointBinder("example.service"),
            nullptr);
}

TEST_F(BinderServerTest, BuildAndStartFailed) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  // Error: binder address should begin with binder:
  server_builder.AddListeningPort("localhost:12345",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  EXPECT_EQ(server, nullptr);
}

TEST_F(BinderServerTest, CreateChannelWithEndpointBinder) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  void* raw_endpoint_binder =
      grpc::experimental::binder::GetEndpointBinder("example.service");
  std::unique_ptr<grpc_binder::Binder> endpoint_binder =
      absl::make_unique<grpc_binder::end2end_testing::FakeBinder>(
          static_cast<grpc_binder::end2end_testing::FakeEndpoint*>(
              raw_endpoint_binder));
  std::shared_ptr<grpc::Channel> channel =
      grpc::testing::CreateBinderChannel(std::move(endpoint_binder));
  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub =
      grpc::testing::EchoTestService::NewStub(channel);
  grpc::testing::EchoRequest request;
  grpc::testing::EchoResponse response;
  grpc::ClientContext context;
  request.set_message("BinderServerBuilder");
  grpc::Status status = stub->Echo(&context, request, &response);
  EXPECT_TRUE(status.ok());
  EXPECT_EQ(response.message(), "BinderServerBuilder");
  server->Shutdown();
}

TEST_F(BinderServerTest, CreateChannelWithEndpointBinderMultipleConnections) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service.multiple.connections",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  void* raw_endpoint_binder = grpc::experimental::binder::GetEndpointBinder(
      "example.service.multiple.connections");
  constexpr size_t kNumThreads = 128;

  auto thread_fn = [&](size_t id) {
    std::unique_ptr<grpc_binder::Binder> endpoint_binder =
        absl::make_unique<grpc_binder::end2end_testing::FakeBinder>(
            static_cast<grpc_binder::end2end_testing::FakeEndpoint*>(
                raw_endpoint_binder));
    std::shared_ptr<grpc::Channel> channel =
        grpc::testing::CreateBinderChannel(std::move(endpoint_binder));
    std::unique_ptr<grpc::testing::EchoTestService::Stub> stub =
        grpc::testing::EchoTestService::NewStub(channel);
    grpc::testing::EchoRequest request;
    grpc::testing::EchoResponse response;
    grpc::ClientContext context;
    request.set_message(absl::StrFormat("BinderServerBuilder-%d", id));
    grpc::Status status = stub->Echo(&context, request, &response);
    EXPECT_TRUE(status.ok());
    EXPECT_EQ(response.message(),
              absl::StrFormat("BinderServerBuilder-%d", id));
  };

  std::vector<std::thread> threads(kNumThreads);
  for (size_t i = 0; i < kNumThreads; ++i) {
    threads[i] = std::thread(thread_fn, i);
  }
  for (auto& thr : threads) {
    thr.join();
  }
  server->Shutdown();
}

TEST_F(BinderServerTest, CreateChannelWithEndpointBinderParallelRequests) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  void* raw_endpoint_binder =
      grpc::experimental::binder::GetEndpointBinder("example.service");
  std::unique_ptr<grpc_binder::Binder> endpoint_binder =
      absl::make_unique<grpc_binder::end2end_testing::FakeBinder>(
          static_cast<grpc_binder::end2end_testing::FakeEndpoint*>(
              raw_endpoint_binder));
  std::shared_ptr<grpc::Channel> channel =
      grpc::testing::CreateBinderChannel(std::move(endpoint_binder));
  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub =
      grpc::testing::EchoTestService::NewStub(channel);

  constexpr size_t kNumRequests = 128;

  auto thread_fn = [&](size_t id) {
    grpc::testing::EchoRequest request;
    std::string msg = absl::StrFormat("BinderServerBuilder-%d", id);
    request.set_message(msg);
    grpc::testing::EchoResponse response;
    grpc::ClientContext context;
    grpc::Status status = stub->Echo(&context, request, &response);
    EXPECT_TRUE(status.ok());
    EXPECT_EQ(response.message(), msg);
  };
  std::vector<std::thread> threads(kNumRequests);
  for (size_t i = 0; i < kNumRequests; ++i) {
    threads[i] = std::thread(thread_fn, i);
  }
  for (auto& thr : threads) {
    thr.join();
  }
  server->Shutdown();
}

}  // namespace

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  grpc::testing::TestEnvironment env(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>[fixit] Scale down large tests (#30678)<commit_after>// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/core/ext/transport/binder/server/binder_server.h"

#include <memory>
#include <thread>
#include <vector>

#include <gtest/gtest.h>

#include "absl/memory/memory.h"

#include <grpcpp/grpcpp.h>
#include <grpcpp/impl/grpc_library.h>
#include <grpcpp/security/binder_credentials.h>
#include <grpcpp/security/binder_security_policy.h>

#include "src/core/ext/transport/binder/client/channel_create_impl.h"
#include "src/core/ext/transport/binder/server/binder_server.h"
#include "test/core/transport/binder/end2end/fake_binder.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"

namespace grpc {
namespace testing {

namespace {

class BinderServerCredentialsImpl final : public ServerCredentials {
 public:
  int AddPortToServer(const std::string& addr, grpc_server* server) override {
    return grpc_core::AddBinderPort(
        addr, server,
        [](grpc_binder::TransactionReceiver::OnTransactCb transact_cb) {
          return absl::make_unique<
              grpc_binder::end2end_testing::FakeTransactionReceiver>(
              nullptr, std::move(transact_cb));
        },
        std::make_shared<
            grpc::experimental::binder::UntrustedSecurityPolicy>());
  }

  void SetAuthMetadataProcessor(
      const std::shared_ptr<AuthMetadataProcessor>& /*processor*/) override {
    GPR_ASSERT(false);
  }

 private:
  bool IsInsecure() const override { return true; }
};

}  // namespace

std::shared_ptr<ServerCredentials> BinderServerCredentials() {
  return std::shared_ptr<ServerCredentials>(new BinderServerCredentialsImpl());
}

std::shared_ptr<grpc::Channel> CreateBinderChannel(
    std::unique_ptr<grpc_binder::Binder> endpoint_binder) {
  grpc::internal::GrpcLibrary init_lib;
  init_lib.init();

  return grpc::CreateChannelInternal(
      "",
      grpc::internal::CreateDirectBinderChannelImplForTesting(
          std::move(endpoint_binder), nullptr,
          std::make_shared<
              grpc::experimental::binder::UntrustedSecurityPolicy>()),
      std::vector<std::unique_ptr<
          grpc::experimental::ClientInterceptorFactoryInterface>>());
}

}  // namespace testing
}  // namespace grpc

namespace {

class BinderServerTest : public ::testing::Test {
 public:
  BinderServerTest() {
    grpc_binder::end2end_testing::g_transaction_processor =
        new grpc_binder::end2end_testing::TransactionProcessor();
  }
  ~BinderServerTest() override {
    delete grpc_binder::end2end_testing::g_transaction_processor;
  }
  static void SetUpTestSuite() { grpc_init(); }
  static void TearDownTestSuite() { grpc_shutdown(); }
};

#ifndef GPR_SUPPORT_BINDER_TRANSPORT
TEST(BinderServerCredentialsTest,
     FailedInEnvironmentsNotSupportingBinderTransport) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort(
      "binder:fail",
      grpc::experimental::BinderServerCredentials(
          std::make_shared<
              grpc::experimental::binder::UntrustedSecurityPolicy>()));
  EXPECT_EQ(server_builder.BuildAndStart(), nullptr);
}
#endif  // !GPR_SUPPORT_BINDER_TRANSPORT

TEST_F(BinderServerTest, BuildAndStart) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  EXPECT_NE(grpc::experimental::binder::GetEndpointBinder("example.service"),
            nullptr);
  server->Shutdown();
  EXPECT_EQ(grpc::experimental::binder::GetEndpointBinder("example.service"),
            nullptr);
}

TEST_F(BinderServerTest, BuildAndStartFailed) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  // Error: binder address should begin with binder:
  server_builder.AddListeningPort("localhost:12345",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  EXPECT_EQ(server, nullptr);
}

TEST_F(BinderServerTest, CreateChannelWithEndpointBinder) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  void* raw_endpoint_binder =
      grpc::experimental::binder::GetEndpointBinder("example.service");
  std::unique_ptr<grpc_binder::Binder> endpoint_binder =
      absl::make_unique<grpc_binder::end2end_testing::FakeBinder>(
          static_cast<grpc_binder::end2end_testing::FakeEndpoint*>(
              raw_endpoint_binder));
  std::shared_ptr<grpc::Channel> channel =
      grpc::testing::CreateBinderChannel(std::move(endpoint_binder));
  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub =
      grpc::testing::EchoTestService::NewStub(channel);
  grpc::testing::EchoRequest request;
  grpc::testing::EchoResponse response;
  grpc::ClientContext context;
  request.set_message("BinderServerBuilder");
  grpc::Status status = stub->Echo(&context, request, &response);
  EXPECT_TRUE(status.ok());
  EXPECT_EQ(response.message(), "BinderServerBuilder");
  server->Shutdown();
}

TEST_F(BinderServerTest, CreateChannelWithEndpointBinderMultipleConnections) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service.multiple.connections",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  void* raw_endpoint_binder = grpc::experimental::binder::GetEndpointBinder(
      "example.service.multiple.connections");
  constexpr size_t kNumThreads = 10;

  auto thread_fn = [&](size_t id) {
    std::unique_ptr<grpc_binder::Binder> endpoint_binder =
        absl::make_unique<grpc_binder::end2end_testing::FakeBinder>(
            static_cast<grpc_binder::end2end_testing::FakeEndpoint*>(
                raw_endpoint_binder));
    std::shared_ptr<grpc::Channel> channel =
        grpc::testing::CreateBinderChannel(std::move(endpoint_binder));
    std::unique_ptr<grpc::testing::EchoTestService::Stub> stub =
        grpc::testing::EchoTestService::NewStub(channel);
    grpc::testing::EchoRequest request;
    grpc::testing::EchoResponse response;
    grpc::ClientContext context;
    request.set_message(absl::StrFormat("BinderServerBuilder-%d", id));
    grpc::Status status = stub->Echo(&context, request, &response);
    EXPECT_TRUE(status.ok());
    EXPECT_EQ(response.message(),
              absl::StrFormat("BinderServerBuilder-%d", id));
  };

  std::vector<std::thread> threads(kNumThreads);
  for (size_t i = 0; i < kNumThreads; ++i) {
    threads[i] = std::thread(thread_fn, i);
  }
  for (auto& thr : threads) {
    thr.join();
  }
  server->Shutdown();
}

TEST_F(BinderServerTest, CreateChannelWithEndpointBinderParallelRequests) {
  grpc::ServerBuilder server_builder;
  grpc::testing::TestServiceImpl service;
  server_builder.RegisterService(&service);
  server_builder.AddListeningPort("binder:example.service",
                                  grpc::testing::BinderServerCredentials());
  std::unique_ptr<grpc::Server> server = server_builder.BuildAndStart();
  void* raw_endpoint_binder =
      grpc::experimental::binder::GetEndpointBinder("example.service");
  std::unique_ptr<grpc_binder::Binder> endpoint_binder =
      absl::make_unique<grpc_binder::end2end_testing::FakeBinder>(
          static_cast<grpc_binder::end2end_testing::FakeEndpoint*>(
              raw_endpoint_binder));
  std::shared_ptr<grpc::Channel> channel =
      grpc::testing::CreateBinderChannel(std::move(endpoint_binder));
  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub =
      grpc::testing::EchoTestService::NewStub(channel);

  constexpr size_t kNumRequests = 10;

  auto thread_fn = [&](size_t id) {
    grpc::testing::EchoRequest request;
    std::string msg = absl::StrFormat("BinderServerBuilder-%d", id);
    request.set_message(msg);
    grpc::testing::EchoResponse response;
    grpc::ClientContext context;
    grpc::Status status = stub->Echo(&context, request, &response);
    EXPECT_TRUE(status.ok());
    EXPECT_EQ(response.message(), msg);
  };
  std::vector<std::thread> threads(kNumRequests);
  for (size_t i = 0; i < kNumRequests; ++i) {
    threads[i] = std::thread(thread_fn, i);
  }
  for (auto& thr : threads) {
    thr.join();
  }
  server->Shutdown();
}

}  // namespace

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  grpc::testing::TestEnvironment env(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <set>
#include <sstream>

#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>

class Context
{
    std::string m_aClassName;
    std::string m_aClassPrefix;

public:
    Context(const std::string& rClassName, const std::string& rClassPrefix)
        : m_aClassName(rClassName),
          m_aClassPrefix(rClassPrefix)
    {
    }

    bool match(const std::string& rName) const
    {
        if (m_aClassName == "")
            return rName.find(m_aClassPrefix) == 0;
        else
            return rName == m_aClassName;
    }
};

class Visitor : public clang::RecursiveASTVisitor<Visitor>
{
    const Context m_rContext;
    bool m_bFound;

public:
    Visitor(const Context& rContext)
        : m_rContext(rContext),
          m_bFound(false)
    {
    }

    bool getFound()
    {
        return m_bFound;
    }

    /*
     * class C
     * {
     * public:
     *     int nX; <- Handles this declaration.
     * };
     */
    bool VisitFieldDecl(clang::FieldDecl* pDecl)
    {
        clang::RecordDecl* pRecord = pDecl->getParent();

        if (m_rContext.match(pRecord->getQualifiedNameAsString()))
        {
            std::string aName = pDecl->getNameAsString();
            if (aName.find("m_") != 0)
            {
                if (aName.find("m") == 0)
                    aName.insert(1, "_");
                else
                    aName.insert(0, "m_");
                std::cout << pRecord->getQualifiedNameAsString() << "::" << pDecl->getNameAsString() << "," << aName << std::endl;
                m_bFound = true;
            }
        }

        return true;
    }

};

class ASTConsumer : public clang::ASTConsumer
{
    const Context& m_rContext;

public:
    ASTConsumer(const Context& rContext)
        : m_rContext(rContext)
    {
    }

    virtual void HandleTranslationUnit(clang::ASTContext& rContext)
    {
        if (rContext.getDiagnostics().hasErrorOccurred())
            return;

        Visitor aVisitor(m_rContext);
        aVisitor.TraverseDecl(rContext.getTranslationUnitDecl());
        if (aVisitor.getFound())
            exit(1);
    }
};

class FrontendAction
{
    const Context& m_rContext;

public:
    FrontendAction(const Context& rContext)
        : m_rContext(rContext)
    {
    }

    clang::ASTConsumer* newASTConsumer()
    {
        return new ASTConsumer(m_rContext);
    }
};

int main(int argc, const char** argv)
{
    llvm::cl::OptionCategory aCategory("find-unprefixed-members options");
    llvm::cl::opt<std::string> aClassName("class-name",
                                          llvm::cl::desc("Qualified name (namespace::Class)."),
                                          llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aClassPrefix("class-prefix",
                                            llvm::cl::desc("Qualified name prefix (e.g. namespace::Cl)."),
                                            llvm::cl::cat(aCategory));
    clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);

    if (aClassName.empty() && aClassPrefix.empty())
    {
        std::cerr << "-class-name or -class-prefix is required." << std::endl;
        return 1;
    }

    clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());

    Context aContext(aClassName, aClassPrefix);
    FrontendAction aAction(aContext);
    std::unique_ptr<clang::tooling::FrontendActionFactory> pFactory = clang::tooling::newFrontendActionFactory(&aAction);
    return aTool.run(pFactory.get());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>clang: for now, maFoo is as good as m_aFoo<commit_after>#include <fstream>
#include <iostream>
#include <set>
#include <sstream>

#include <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>

class Context
{
    std::string m_aClassName;
    std::string m_aClassPrefix;

public:
    Context(const std::string& rClassName, const std::string& rClassPrefix)
        : m_aClassName(rClassName),
          m_aClassPrefix(rClassPrefix)
    {
    }

    bool match(const std::string& rName) const
    {
        if (m_aClassName == "")
            return rName.find(m_aClassPrefix) == 0;
        else
            return rName == m_aClassName;
    }
};

class Visitor : public clang::RecursiveASTVisitor<Visitor>
{
    const Context m_rContext;
    bool m_bFound;

public:
    Visitor(const Context& rContext)
        : m_rContext(rContext),
          m_bFound(false)
    {
    }

    bool getFound()
    {
        return m_bFound;
    }

    /*
     * class C
     * {
     * public:
     *     int nX; <- Handles this declaration.
     * };
     */
    bool VisitFieldDecl(clang::FieldDecl* pDecl)
    {
        clang::RecordDecl* pRecord = pDecl->getParent();

        if (m_rContext.match(pRecord->getQualifiedNameAsString()))
        {
            std::string aName = pDecl->getNameAsString();
            if (aName.find("m") != 0)
            {
                aName.insert(0, "m_");
                std::cout << pRecord->getQualifiedNameAsString() << "::" << pDecl->getNameAsString() << "," << aName << std::endl;
                m_bFound = true;
            }
        }

        return true;
    }

};

class ASTConsumer : public clang::ASTConsumer
{
    const Context& m_rContext;

public:
    ASTConsumer(const Context& rContext)
        : m_rContext(rContext)
    {
    }

    virtual void HandleTranslationUnit(clang::ASTContext& rContext)
    {
        if (rContext.getDiagnostics().hasErrorOccurred())
            return;

        Visitor aVisitor(m_rContext);
        aVisitor.TraverseDecl(rContext.getTranslationUnitDecl());
        if (aVisitor.getFound())
            exit(1);
    }
};

class FrontendAction
{
    const Context& m_rContext;

public:
    FrontendAction(const Context& rContext)
        : m_rContext(rContext)
    {
    }

    clang::ASTConsumer* newASTConsumer()
    {
        return new ASTConsumer(m_rContext);
    }
};

int main(int argc, const char** argv)
{
    llvm::cl::OptionCategory aCategory("find-unprefixed-members options");
    llvm::cl::opt<std::string> aClassName("class-name",
                                          llvm::cl::desc("Qualified name (namespace::Class)."),
                                          llvm::cl::cat(aCategory));
    llvm::cl::opt<std::string> aClassPrefix("class-prefix",
                                            llvm::cl::desc("Qualified name prefix (e.g. namespace::Cl)."),
                                            llvm::cl::cat(aCategory));
    clang::tooling::CommonOptionsParser aParser(argc, argv, aCategory);

    if (aClassName.empty() && aClassPrefix.empty())
    {
        std::cerr << "-class-name or -class-prefix is required." << std::endl;
        return 1;
    }

    clang::tooling::ClangTool aTool(aParser.getCompilations(), aParser.getSourcePathList());

    Context aContext(aClassName, aClassPrefix);
    FrontendAction aAction(aContext);
    std::unique_ptr<clang::tooling::FrontendActionFactory> pFactory = clang::tooling::newFrontendActionFactory(&aAction);
    return aTool.run(pFactory.get());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>