Changeset 3205 in CLRX


Ignore:
Timestamp:
Jun 28, 2017, 3:16:27 PM (3 years ago)
Author:
matszpk
Message:

CLRadeonExtender: Add routines to find Mesa OpenCL library and llvm-config utility.
Add routines to detect Mesa3D version and LLVM compiler version.

Location:
CLRadeonExtender/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/CLRX/amdbin/GalliumBinaries.h

    r3195 r3205  
    464464};
    465465
     466/// detect driver version in the system
     467extern uint32_t detectMesaDriverVersion();
     468/// detect LLVM compiler version in the system
     469extern uint32_t detectLLVMCompilerVersion();
     470
    466471};
    467472
  • CLRadeonExtender/trunk/CLRX/utils/Utilities.h

    r3203 r3205  
    717717extern std::string findMesaOCL();
    718718
     719/// find LLVM config, returns path if found, otherwise returns empty string
     720extern std::string findLLVMConfig();
     721
    719722/*
    720723 * Reference support
  • CLRadeonExtender/trunk/amdbin/GalliumBinaries.cpp

    r3159 r3205  
    2525#include <utility>
    2626#include <memory>
     27#include <fstream>
    2728#include <CLRX/utils/Utilities.h>
    2829#include <CLRX/utils/MemAccess.h>
     
    758759    generateInternal(nullptr, &v, nullptr);
    759760}
     761
     762static const char* mesaOclMagicString = "OpenCL 1.1 MESA";
     763static const char* mesaOclMagicString2 = "OpenCL 1.1 Mesa";
     764static std::mutex detectionMutex;
     765static uint64_t detectionFileTimestamp = 0;
     766static std::string detectionMesaOclPath;
     767static uint64_t detectionLLVMFileTimestamp = 0;
     768static std::string detectionLlvmConfigPath;
     769static uint32_t detectedDriverVersion = 0;
     770static uint32_t detectedLLVMVersion = 0;
     771
     772static std::string escapePath(const std::string& path)
     773{
     774    std::string newPath;
     775    for (char c: path)
     776        if (c == CLRX_NATIVE_DIR_SEP)
     777            newPath.append("%#");
     778        else if (c == '%')
     779            newPath.append("%%");
     780        else if (c == ':')
     781            newPath.append("%$");
     782        else
     783            newPath += c;
     784    return newPath;
     785}
     786
     787uint32_t CLRX::detectMesaDriverVersion()
     788{
     789    std::lock_guard<std::mutex> lock(detectionMutex);
     790    std::string mesaOclPath = findMesaOCL();
     791   
     792    bool notThisSameFile = false;
     793    if (mesaOclPath != detectionMesaOclPath)
     794    {
     795        notThisSameFile = true;
     796        detectionMesaOclPath = mesaOclPath;
     797    }
     798   
     799    uint64_t timestamp = 0;
     800    try
     801    { timestamp = getFileTimestamp(mesaOclPath.c_str()); }
     802    catch(const Exception& ex)
     803    { }
     804   
     805    if (!notThisSameFile && timestamp == detectionFileTimestamp)
     806        return detectedDriverVersion;
     807   
     808    std::string clrxTimestampPath = getHomeDir();
     809    if (!clrxTimestampPath.empty())
     810    {   // first, we check from stored version in config files
     811        clrxTimestampPath = joinPaths(clrxTimestampPath, ".clrxmesaocltstamp");
     812        try
     813        { makeDir(clrxTimestampPath.c_str()); }
     814        catch(const std::exception& ex)
     815        { }
     816        // file path
     817        clrxTimestampPath = joinPaths(clrxTimestampPath, escapePath(mesaOclPath));
     818        try
     819        {
     820        std::ifstream ifs(clrxTimestampPath.c_str(), std::ios::binary);
     821        if (ifs)
     822        {   // read driver version from stored config files
     823            ifs.exceptions(std::ios::badbit | std::ios::failbit);
     824            uint64_t readedTimestamp = 0;
     825            uint32_t readedVersion = 0;
     826            ifs >> readedTimestamp >> readedVersion;
     827            if (readedTimestamp!=0 && readedVersion!=0 && timestamp==readedTimestamp)
     828            {   // amdocl has not been changed
     829                detectionFileTimestamp = readedTimestamp;
     830                detectedDriverVersion = readedVersion;
     831                return readedVersion;
     832            }
     833        }
     834        }
     835        catch(const std::exception& ex)
     836        { }
     837    }
     838    detectionFileTimestamp = timestamp;
     839    detectedDriverVersion = 0;
     840    try
     841    {
     842        std::ifstream fs(mesaOclPath.c_str(), std::ios::binary);
     843        if (!fs) return 0;
     844        FastInputBuffer fib(256, fs);
     845        size_t index = 0;
     846        while (mesaOclMagicString[index]!=0)
     847        {
     848            int c = fib.get();
     849            if (c == std::streambuf::traits_type::eof())
     850                break;
     851            if (mesaOclMagicString[index]==c)
     852                index++;
     853            else if (mesaOclMagicString2[index]==c)
     854                index++;
     855            else // reset
     856                index=0;
     857        }
     858        if (mesaOclMagicString[index]==0)
     859        { //
     860            char buf[30];
     861            ::memset(buf, 0, 30);
     862            if (fib.get()!=' ')
     863                return 0; // skip space
     864            // get driver version
     865            fib.read(buf, 30);
     866           
     867            const char* next;
     868            detectedDriverVersion = cstrtoui(buf, buf+30, next)*10000;
     869            if (next!=buf+30 && *next=='.') // minor version
     870                detectedDriverVersion += (cstrtoui(next+1, buf+30, next)%100)*100;
     871            if (next!=buf+30 && *next=='.') // micro version
     872                detectedDriverVersion += cstrtoui(next+1, buf+30, next)%100;
     873        }
     874       
     875        // write to config
     876        if (!clrxTimestampPath.empty()) // if clrxamdocltstamp set
     877        {   // write to
     878            std::ofstream ofs(clrxTimestampPath.c_str(), std::ios::binary);
     879            ofs << detectionFileTimestamp << " " << detectedDriverVersion;
     880        }
     881    }
     882    catch(const std::exception& ex)
     883    { }
     884    return detectedDriverVersion;
     885}
     886
     887uint32_t CLRX::detectLLVMCompilerVersion()
     888{
     889    std::lock_guard<std::mutex> lock(detectionMutex);
     890    std::string llvmConfigPath = findLLVMConfig();
     891   
     892    bool notThisSameFile = false;
     893    if (llvmConfigPath != detectionLlvmConfigPath)
     894    {
     895        notThisSameFile = true;
     896        detectionLlvmConfigPath = llvmConfigPath;
     897    }
     898   
     899    uint64_t timestamp = 0;
     900    try
     901    { timestamp = getFileTimestamp(llvmConfigPath.c_str()); }
     902    catch(const Exception& ex)
     903    { }
     904   
     905    if (!notThisSameFile && timestamp == detectionLLVMFileTimestamp)
     906        return detectedLLVMVersion;
     907   
     908    std::string clrxTimestampPath = getHomeDir();
     909    if (!clrxTimestampPath.empty())
     910    {   // first, we check from stored version in config files
     911        clrxTimestampPath = joinPaths(clrxTimestampPath, ".clrxllvmcfgtstamp");
     912        try
     913        { makeDir(clrxTimestampPath.c_str()); }
     914        catch(const std::exception& ex)
     915        { }
     916        // file path
     917        clrxTimestampPath = joinPaths(clrxTimestampPath, escapePath(llvmConfigPath));
     918        try
     919        {
     920        std::ifstream ifs(clrxTimestampPath.c_str(), std::ios::binary);
     921        if (ifs)
     922        {   // read driver version from stored config files
     923            ifs.exceptions(std::ios::badbit | std::ios::failbit);
     924            uint64_t readedTimestamp = 0;
     925            uint32_t readedVersion = 0;
     926            ifs >> readedTimestamp >> readedVersion;
     927            if (readedTimestamp!=0 && readedVersion!=0 && timestamp==readedTimestamp)
     928            {   // amdocl has not been changed
     929                detectionLLVMFileTimestamp = readedTimestamp;
     930                detectedLLVMVersion = readedVersion;
     931                return readedVersion;
     932            }
     933        }
     934        }
     935        catch(const std::exception& ex)
     936        { }
     937    }
     938    detectionLLVMFileTimestamp = timestamp;
     939    detectedLLVMVersion = 0;
     940    try
     941    {
     942        const char* arguments[3] = { llvmConfigPath.c_str(), "--version", nullptr };
     943        Array<cxbyte> out = runExecWithOutput(llvmConfigPath.c_str(), arguments);
     944        const char* next;
     945        const char* end = ((const char*)out.data()) + out.size();
     946        detectedLLVMVersion = cstrtoui(((const char*)out.data()), end, next)*10000;
     947        if (next!=end && *next=='.') // minor version
     948            detectedLLVMVersion += (cstrtoui(next+1, end, next)%100)*100;
     949        if (next!=end && *next=='.') // micro version
     950            detectedLLVMVersion += cstrtoui(next+1, end, next)%100;
     951       
     952        // write to config
     953        if (!clrxTimestampPath.empty()) // if clrxamdocltstamp set
     954        {   // write to
     955            std::ofstream ofs(clrxTimestampPath.c_str(), std::ios::binary);
     956            ofs << detectionLLVMFileTimestamp << " " << detectedLLVMVersion;
     957        }
     958    }
     959    catch(const std::exception& ex)
     960    { }
     961    return detectedLLVMVersion;
     962}
  • CLRadeonExtender/trunk/utils/Utilities.cpp

    r3204 r3205  
    624624}
    625625
     626static std::string findFileByEnvPaths(const char* envName, const char* fileName)
     627{
     628    // find by path
     629    const std::string paths = parseEnvVariable<std::string>(envName);
     630    for (size_t i = 0; i != std::string::npos; )
     631    {
     632#ifndef HAVE_WINDOWS
     633        size_t nexti = paths.find(':', i);
     634#else
     635        size_t nexti = paths.find(';', i);
     636#endif
     637        std::string path;
     638        if (nexti != std::string::npos)
     639        {   // next
     640            path = paths.substr(i, nexti-i);
     641            i = nexti+1;
     642        }
     643        else
     644        {   // last
     645            path = paths.substr(i);
     646            i = std::string::npos;
     647        }
     648        if (path.empty())
     649            continue; // skip empty path
     650        std::string filePath = joinPaths(path, fileName);
     651        if (isFileExists(filePath.c_str()))
     652            return filePath;
     653    }
     654    return "";
     655}
     656
    626657static const char* libAmdOCLPaths[] =
    627658{
     
    656687    }
    657688    else
     689    {
    658690        for (const char* libPath: libAmdOCLPaths)
    659691        {
     
    662694                return amdOclPath;
    663695        }
     696#ifndef HAVE_WINDOWS
     697        amdOclPath = findFileByEnvPaths("LD_LIBRARY_PATH", DEFAULT_AMDOCLNAME);
     698#else
     699        amdOclPath = findFileByEnvPaths("PATH", DEFAULT_AMDOCLNAME);
     700#endif
     701        if (!amdOclPath.empty())
     702            return amdOclPath;
     703    }
    664704    return "";
    665705}
     
    681721std::string CLRX::findMesaOCL()
    682722{
    683     std::string amdOclPath = parseEnvVariable<std::string>("CLRX_MESAOCL_PATH", "");
    684     if (!amdOclPath.empty())
    685     {
    686         if (isFileExists(amdOclPath.c_str()))
    687             return amdOclPath;
     723#ifndef HAVE_WINDOWS
     724    std::string mesaOclPath = parseEnvVariable<std::string>("CLRX_MESAOCL_PATH", "");
     725    if (!mesaOclPath.empty())
     726    {
     727        if (isFileExists(mesaOclPath.c_str()))
     728            return mesaOclPath;
    688729    }
    689730    else
     
    691732        for (const char* libPath: libMesaOCLPaths)
    692733        {
    693             amdOclPath = joinPaths(libPath, "libMesaOpenCL.so.1");
    694             if (isFileExists(amdOclPath.c_str()))
    695                 return amdOclPath;
     734            mesaOclPath = joinPaths(libPath, "libMesaOpenCL.so.1");
     735            if (isFileExists(mesaOclPath.c_str()))
     736                return mesaOclPath;
    696737        }
    697738#ifdef HAVE_64BIT
     
    704745            return "/usr/lib/OpenCL/vendors/mesa/libOpenCL.so";
    705746#endif
    706     }
     747        mesaOclPath = findFileByEnvPaths("LD_LIBRARY_PATH", "libMesaOpenCL.so.1");
     748        if (!mesaOclPath.empty())
     749            return mesaOclPath;
     750    }
     751#endif
    707752    return "";
    708753}
     754
     755std::string CLRX::findLLVMConfig()
     756{
     757    std::string llvmConfigPath = parseEnvVariable<std::string>("CLRX_LLVMCONFIG_PATH", "");
     758    if (!llvmConfigPath.empty())
     759    {
     760        if (isFileExists(llvmConfigPath.c_str()))
     761            return llvmConfigPath;
     762        return "";
     763    }
     764    else
     765    {
     766#ifndef HAVE_WINDOWS
     767        if (isFileExists("/usr/bin/llvm-config"))
     768            return "/usr/bin/llvm-config";
     769#endif
     770        // find by path
     771        return findFileByEnvPaths("PATH", "llvm-config");
     772    }
     773}
Note: See TracChangeset for help on using the changeset viewer.