<commit_before>/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include "symbol_manager.hpp"
#include <algorithm>
#include <string>
#include <cmath>

using std::string;
using std::replace;

namespace unified
{

static const string LIB_AF_BKND_NAME[NUM_BACKENDS] = {"cpu", "cuda", "opencl"};
#if defined(OS_WIN)
static const string LIB_AF_BKND_PREFIX = "af";
static const string LIB_AF_BKND_SUFFIX = ".dll";
#define RTLD_LAZY 0
#else
static const string LIB_AF_BKND_PREFIX = "libaf";
#if defined(__APPLE__)
static const string LIB_AF_BKND_SUFFIX = ".dylib";
#else
static const string LIB_AF_BKND_SUFFIX = ".so";
#endif // APPLE
#endif

static const string LIB_AF_ENVARS[NUM_ENV_VARS] = {"AF_PATH", "AF_BUILD_PATH"};
static const string LIB_AF_RPATHS[NUM_ENV_VARS] = {"/lib/", "/src/backend/"};
static const bool LIB_AF_RPATH_SUFFIX[NUM_ENV_VARS] = {false, true};

inline string getBkndLibName(const int backend_index)
{
    int i = backend_index >=0 && backend_index<NUM_BACKENDS ? backend_index : 0;
    return LIB_AF_BKND_PREFIX + LIB_AF_BKND_NAME[i] + LIB_AF_BKND_SUFFIX;
}

inline std::string getEnvVar(const std::string &key)
{
#if defined(OS_WIN)
    DWORD bufSize = 32767; // limit according to GetEnvironment Variable documentation
    string retVal;
    retVal.resize(bufSize);
    bufSize = GetEnvironmentVariable(key.c_str(), &retVal[0], bufSize);
    if (!bufSize) {
        return string("");
    } else {
        retVal.resize(bufSize);
        return retVal;
    }
#else
    char * str = getenv(key.c_str());
    return str==NULL ? string("") : string(str);
#endif
}

/*flag parameter is not used on windows platform */
LibHandle openDynLibrary(const int bknd_idx, int flag=RTLD_LAZY)
{
    /*
     * The default search path is the colon separated list of
     * paths stored in the environment variables:
     * * LD_LIBRARY_PATH(Linux/Unix/Apple)
     * * DYLD_LIBRARY_PATH (Apple)
     * * PATH (Windows)
    */
    string bkndLibName = getBkndLibName(bknd_idx);
    string show_flag = getEnvVar("AF_SHOW_LOAD_PATH");
    bool show_load_path = show_flag=="1";

#if defined(OS_WIN)
    HMODULE retVal = LoadLibrary(bkndLibName.c_str());
#else
    LibHandle retVal = dlopen(bkndLibName.c_str(), flag);
#endif
    if(retVal != NULL) { // Success
        if (show_load_path)
            printf("Using %s from system path\n", bkndLibName.c_str());
    } else {
        /*
         * In the event that dlopen returns NULL, search for the lib
         * in hard coded paths based on the environment variables
         * defined in the constant string array LIB_AF_PATHS
         * * AF_PATH
         * * AF_BUILD_PATH
         *
         * Note: This does not guarantee successful loading as the dependent
         * libraries may still not load
        */

        for (int i=0; i<NUM_ENV_VARS; ++i) {
            string abs_path = getEnvVar(LIB_AF_ENVARS[i])
                                 + LIB_AF_RPATHS[i]
                                 + (LIB_AF_RPATH_SUFFIX[i] ? LIB_AF_BKND_NAME[bknd_idx]+"/" : "")
                                 + bkndLibName;
#if defined(OS_WIN)
            replace(abs_path.begin(), abs_path.end(), '/', '\\');
            retVal = LoadLibrary(abs_path.c_str());
#else
            retVal = dlopen(abs_path.c_str(), flag);
#endif
            if (retVal!=NULL) {
                if (show_load_path)
                    printf("Using %s\n", abs_path.c_str());
                // if the current absolute path based dlopen
                // search is a success, then abandon search
                // and proceed for compute
                break;
            }
        }

#if !defined(OS_WIN)
        /*
         * If Linux/OSX, then the following are also checked
         * (only if lib is not found)
         * /opt/arrayfire/lib
         * /opt/arrayfire-3/lib
         * /usr/local/lib
         * /usr/local/arrayfire/lib
         * /usr/local/arrayfire-3/lib
        */
        if (retVal == NULL) {
            static const char* extraLibPaths[] = {"/opt/arrayfire-3/lib/",
                                                  "/opt/arrayfire/lib/",
                                                  "/usr/local/lib/",
                                                  "/usr/local/arrayfire-3/lib/",
                                                  "/usr/local/arrayfire/lib/",
                                                 };
            const int nPaths = sizeof(extraLibPaths) / sizeof(extraLibPaths[0]);

            for (int i = 0; i < nPaths; ++i) {
                string abs_path = extraLibPaths[i] + bkndLibName;
                retVal = dlopen(abs_path.c_str(), flag);
                if (retVal != NULL) {
                    if (show_load_path)
                        printf("Using %s\n", abs_path.c_str());
                    // if the current absolute path based dlopen
                    // search is a success, then abandon search
                    // and proceed for compute
                    break;
                }
            }
        }
#endif
    }

    return retVal;
}

void closeDynLibrary(LibHandle handle)
{
#if defined(OS_WIN)
    FreeLibrary(handle);
#else
    dlclose(handle);
#endif
}

AFSymbolManager& AFSymbolManager::getInstance()
{<commit_msg>Using vector<string> in unified for extra paths<commit_after>/*******************************************************
 * Copyright (c) 2015, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include "symbol_manager.hpp"
#include <algorithm>
#include <string>
#include <cmath>

using std::string;
using std::replace;

namespace unified
{

static const string LIB_AF_BKND_NAME[NUM_BACKENDS] = {"cpu", "cuda", "opencl"};
#if defined(OS_WIN)
static const string LIB_AF_BKND_PREFIX = "af";
static const string LIB_AF_BKND_SUFFIX = ".dll";
#define RTLD_LAZY 0
#else
static const string LIB_AF_BKND_PREFIX = "libaf";
#if defined(__APPLE__)
static const string LIB_AF_BKND_SUFFIX = ".dylib";
#else
static const string LIB_AF_BKND_SUFFIX = ".so";
#endif // APPLE
#endif

static const string LIB_AF_ENVARS[NUM_ENV_VARS] = {"AF_PATH", "AF_BUILD_PATH"};
static const string LIB_AF_RPATHS[NUM_ENV_VARS] = {"/lib/", "/src/backend/"};
static const bool LIB_AF_RPATH_SUFFIX[NUM_ENV_VARS] = {false, true};

inline string getBkndLibName(const int backend_index)
{
    int i = backend_index >=0 && backend_index<NUM_BACKENDS ? backend_index : 0;
    return LIB_AF_BKND_PREFIX + LIB_AF_BKND_NAME[i] + LIB_AF_BKND_SUFFIX;
}

inline std::string getEnvVar(const std::string &key)
{
#if defined(OS_WIN)
    DWORD bufSize = 32767; // limit according to GetEnvironment Variable documentation
    string retVal;
    retVal.resize(bufSize);
    bufSize = GetEnvironmentVariable(key.c_str(), &retVal[0], bufSize);
    if (!bufSize) {
        return string("");
    } else {
        retVal.resize(bufSize);
        return retVal;
    }
#else
    char * str = getenv(key.c_str());
    return str==NULL ? string("") : string(str);
#endif
}

/*flag parameter is not used on windows platform */
LibHandle openDynLibrary(const int bknd_idx, int flag=RTLD_LAZY)
{
    /*
     * The default search path is the colon separated list of
     * paths stored in the environment variables:
     * * LD_LIBRARY_PATH(Linux/Unix/Apple)
     * * DYLD_LIBRARY_PATH (Apple)
     * * PATH (Windows)
    */
    string bkndLibName = getBkndLibName(bknd_idx);
    string show_flag = getEnvVar("AF_SHOW_LOAD_PATH");
    bool show_load_path = show_flag=="1";

#if defined(OS_WIN)
    HMODULE retVal = LoadLibrary(bkndLibName.c_str());
#else
    LibHandle retVal = dlopen(bkndLibName.c_str(), flag);
#endif
    if(retVal != NULL) { // Success
        if (show_load_path)
            printf("Using %s from system path\n", bkndLibName.c_str());
    } else {
        /*
         * In the event that dlopen returns NULL, search for the lib
         * in hard coded paths based on the environment variables
         * defined in the constant string array LIB_AF_PATHS
         * * AF_PATH
         * * AF_BUILD_PATH
         *
         * Note: This does not guarantee successful loading as the dependent
         * libraries may still not load
        */

        for (int i=0; i<NUM_ENV_VARS; ++i) {
            string abs_path = getEnvVar(LIB_AF_ENVARS[i])
                                 + LIB_AF_RPATHS[i]
                                 + (LIB_AF_RPATH_SUFFIX[i] ? LIB_AF_BKND_NAME[bknd_idx]+"/" : "")
                                 + bkndLibName;
#if defined(OS_WIN)
            replace(abs_path.begin(), abs_path.end(), '/', '\\');
            retVal = LoadLibrary(abs_path.c_str());
#else
            retVal = dlopen(abs_path.c_str(), flag);
#endif
            if (retVal!=NULL) {
                if (show_load_path)
                    printf("Using %s\n", abs_path.c_str());
                // if the current absolute path based dlopen
                // search is a success, then abandon search
                // and proceed for compute
                break;
            }
        }

#if !defined(OS_WIN)
        /*
         * If Linux/OSX, then the following are also checked
         * (only if lib is not found)
         * /opt/arrayfire/lib
         * /opt/arrayfire-3/lib
         * /usr/local/lib
         * /usr/local/arrayfire/lib
         * /usr/local/arrayfire-3/lib
        */
        if (retVal == NULL) {
            static
            std::vector<std::string> extraLibPaths {"/opt/arrayfire-3/lib/",
                                                    "/opt/arrayfire/lib/",
                                                    "/usr/local/lib/",
                                                    "/usr/local/arrayfire-3/lib/",
                                                    "/usr/local/arrayfire/lib/",
                                                   };

            for (int i = 0; i < (int)extraLibPaths.size(); ++i) {
                string abs_path = extraLibPaths[i] + bkndLibName;
                retVal = dlopen(abs_path.c_str(), flag);
                if (retVal != NULL) {
                    if (show_load_path)
                        printf("Using %s\n", abs_path.c_str());
                    // if the current absolute path based dlopen
                    // search is a success, then abandon search
                    // and proceed for compute
                    break;
                }
            }
        }
#endif
    }

    return retVal;
}

void closeDynLibrary(LibHandle handle)
{
#if defined(OS_WIN)
    FreeLibrary(handle);
#else
    dlclose(handle);
#endif
}

AFSymbolManager& AFSymbolManager::getInstance()
{
{'fraction_non_alphanumeric': 0.12840713574209905, 'fraction_numerical': 0.004074979625101874, 'mean_word_length': 2.0763231197771588, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5917901', 'n_tokens_mistral': 3460, 'n_tokens_neox': 3300, 'n_words': 820}