2019-06-06 14:21:15 +02:00
|
|
|
/*******************************************************************************
|
|
|
|
* Copyright (c) 2015-2018 Skymind, Inc.
|
|
|
|
*
|
|
|
|
* This program and the accompanying materials are made available under the
|
|
|
|
* terms of the Apache License, Version 2.0 which is available at
|
|
|
|
* https://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.
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
//
|
|
|
|
// Created by raver119 on 06.10.2017.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include "Environment.h"
|
|
|
|
#include <helpers/StringUtils.h>
|
2019-11-13 15:04:59 +01:00
|
|
|
#include <thread>
|
|
|
|
#include <helpers/logger.h>
|
2019-06-06 14:21:15 +02:00
|
|
|
|
2019-08-02 19:01:03 +02:00
|
|
|
#ifdef _OPENMP
|
|
|
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2019-06-06 14:21:15 +02:00
|
|
|
#ifdef __CUDABLAS__
|
|
|
|
|
|
|
|
#include <cuda.h>
|
|
|
|
#include <cuda_runtime.h>
|
2019-09-04 13:41:08 +02:00
|
|
|
#include "BlasVersionHelper.h"
|
2019-06-06 14:21:15 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace nd4j {
|
|
|
|
|
|
|
|
nd4j::Environment::Environment() {
|
2019-11-14 12:35:02 +01:00
|
|
|
_tadThreshold.store(1);
|
2019-06-06 14:21:15 +02:00
|
|
|
_elementThreshold.store(1024);
|
|
|
|
_verbose.store(false);
|
|
|
|
_debug.store(false);
|
|
|
|
_profile.store(false);
|
|
|
|
_precBoost.store(false);
|
|
|
|
_leaks.store(false);
|
|
|
|
_dataType.store(nd4j::DataType::FLOAT32);
|
2019-11-13 15:04:59 +01:00
|
|
|
_maxThreads = std::thread::hardware_concurrency();
|
2019-11-14 12:35:02 +01:00
|
|
|
_maxMasterThreads = _maxThreads.load();
|
2019-06-06 14:21:15 +02:00
|
|
|
|
|
|
|
#ifndef ANDROID
|
|
|
|
const char* omp_threads = std::getenv("OMP_NUM_THREADS");
|
|
|
|
if (omp_threads != nullptr) {
|
|
|
|
try {
|
|
|
|
std::string omp(omp_threads);
|
|
|
|
int val = std::stoi(omp);
|
|
|
|
_maxThreads.store(val);
|
2019-12-19 14:50:08 +01:00
|
|
|
_maxMasterThreads.store(val);
|
2019-06-06 14:21:15 +02:00
|
|
|
} catch (std::invalid_argument &e) {
|
|
|
|
// just do nothing
|
|
|
|
} catch (std::out_of_range &e) {
|
|
|
|
// still do nothing
|
|
|
|
}
|
|
|
|
}
|
2019-11-14 12:35:02 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Defines size of thread pool used for parallelism
|
|
|
|
*/
|
|
|
|
const char* max_threads = std::getenv("SD_MAX_THREADS");
|
|
|
|
if (max_threads != nullptr) {
|
|
|
|
try {
|
|
|
|
std::string t(max_threads);
|
|
|
|
int val = std::stoi(t);
|
|
|
|
_maxThreads.store(val);
|
|
|
|
} catch (std::invalid_argument &e) {
|
|
|
|
// just do nothing
|
|
|
|
} catch (std::out_of_range &e) {
|
|
|
|
// still do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Defines max number of threads usable at once
|
|
|
|
*/
|
|
|
|
const char* max_master_threads = std::getenv("SD_MASTER_THREADS");
|
|
|
|
if (max_master_threads != nullptr) {
|
|
|
|
try {
|
|
|
|
std::string t(max_master_threads);
|
|
|
|
int val = std::stoi(t);
|
|
|
|
_maxMasterThreads.store(val);
|
|
|
|
} catch (std::invalid_argument &e) {
|
|
|
|
// just do nothing
|
|
|
|
} catch (std::out_of_range &e) {
|
|
|
|
// still do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-19 14:50:08 +01:00
|
|
|
if (_maxMasterThreads.load() > _maxThreads.load()) {
|
|
|
|
nd4j_printf("Warning! MAX_MASTER_THREADS > MAX_THREADS, tuning them down to match each other\n","");
|
|
|
|
_maxMasterThreads.store(_maxThreads.load());
|
|
|
|
}
|
|
|
|
|
2019-11-14 12:35:02 +01:00
|
|
|
/**
|
|
|
|
* If this env var is defined - we'll disallow use of platform-specific helpers (mkldnn, cudnn, etc)
|
|
|
|
*/
|
|
|
|
const char* forbid_helpers = std::getenv("SD_FORBID_HELPERS");
|
|
|
|
if (max_master_threads != nullptr) {
|
|
|
|
_allowHelpers = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This var defines max amount of host memory library can allocate
|
|
|
|
*/
|
|
|
|
const char* max_primary_memory = std::getenv("SD_MAX_PRIMARY_BYTES");
|
|
|
|
if (max_primary_memory != nullptr) {
|
|
|
|
try {
|
|
|
|
std::string t(max_primary_memory);
|
|
|
|
auto val = std::stol(t);
|
|
|
|
_maxTotalPrimaryMemory.store(val);
|
|
|
|
} catch (std::invalid_argument &e) {
|
|
|
|
// just do nothing
|
|
|
|
} catch (std::out_of_range &e) {
|
|
|
|
// still do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This var defines max amount of special (i.e. device) memory library can allocate on all devices combined
|
|
|
|
*/
|
|
|
|
const char* max_special_memory = std::getenv("SD_MAX_SPECIAL_BYTES");
|
|
|
|
if (max_special_memory != nullptr) {
|
|
|
|
try {
|
|
|
|
std::string t(max_special_memory);
|
|
|
|
auto val = std::stol(t);
|
|
|
|
_maxTotalSpecialMemory.store(val);
|
|
|
|
} catch (std::invalid_argument &e) {
|
|
|
|
// just do nothing
|
|
|
|
} catch (std::out_of_range &e) {
|
|
|
|
// still do nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This var defines max amount of special (i.e. device) memory library can allocate on all devices combined
|
|
|
|
*/
|
|
|
|
const char* max_device_memory = std::getenv("SD_MAX_DEVICE_BYTES");
|
|
|
|
if (max_device_memory != nullptr) {
|
|
|
|
try {
|
|
|
|
std::string t(max_device_memory);
|
|
|
|
auto val = std::stol(t);
|
|
|
|
_maxDeviceMemory.store(val);
|
|
|
|
} catch (std::invalid_argument &e) {
|
|
|
|
// just do nothing
|
|
|
|
} catch (std::out_of_range &e) {
|
|
|
|
// still do nothing
|
|
|
|
}
|
|
|
|
}
|
2019-06-06 14:21:15 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __CUDABLAS__
|
|
|
|
int devCnt = 0;
|
|
|
|
cudaGetDeviceCount(&devCnt);
|
|
|
|
auto devProperties = new cudaDeviceProp[devCnt];
|
|
|
|
for (int i = 0; i < devCnt; i++) {
|
|
|
|
cudaSetDevice(i);
|
|
|
|
cudaGetDeviceProperties(&devProperties[i], i);
|
|
|
|
|
|
|
|
//cudaDeviceSetLimit(cudaLimitStackSize, 4096);
|
|
|
|
Pair p(devProperties[i].major, devProperties[i].minor);
|
|
|
|
_capabilities.emplace_back(p);
|
|
|
|
}
|
2019-10-26 03:38:08 +02:00
|
|
|
|
|
|
|
BlasVersionHelper ver;
|
|
|
|
_blasMajorVersion = ver._blasMajorVersion;
|
|
|
|
_blasMinorVersion = ver._blasMinorVersion;
|
|
|
|
_blasPatchVersion = ver._blasPatchVersion;
|
2019-06-06 14:21:15 +02:00
|
|
|
|
|
|
|
cudaSetDevice(0);
|
|
|
|
delete[] devProperties;
|
2019-08-02 19:01:03 +02:00
|
|
|
#else
|
2019-11-13 15:04:59 +01:00
|
|
|
|
2019-06-06 14:21:15 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
nd4j::Environment::~Environment() {
|
|
|
|
//
|
|
|
|
}
|
|
|
|
|
2019-11-14 12:35:02 +01:00
|
|
|
void Environment::setMaxPrimaryMemory(uint64_t maxBytes) {
|
|
|
|
_maxTotalPrimaryMemory = maxBytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setMaxSpecialyMemory(uint64_t maxBytes) {
|
|
|
|
_maxTotalSpecialMemory;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setMaxDeviceMemory(uint64_t maxBytes) {
|
|
|
|
_maxDeviceMemory = maxBytes;
|
|
|
|
}
|
|
|
|
|
2019-06-06 14:21:15 +02:00
|
|
|
Environment *Environment::getInstance() {
|
|
|
|
if (_instance == 0)
|
|
|
|
_instance = new Environment();
|
|
|
|
|
|
|
|
return _instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isVerbose() {
|
|
|
|
return _verbose.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isExperimentalBuild() {
|
|
|
|
return _experimental;
|
|
|
|
}
|
|
|
|
|
|
|
|
nd4j::DataType Environment::defaultFloatDataType() {
|
|
|
|
return _dataType.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Pair>& Environment::capabilities() {
|
|
|
|
return _capabilities;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setDefaultFloatDataType(nd4j::DataType dtype) {
|
|
|
|
if (dtype != nd4j::DataType::FLOAT32 && dtype != nd4j::DataType::DOUBLE && dtype != nd4j::DataType::FLOAT8 && dtype != nd4j::DataType::HALF)
|
|
|
|
throw std::runtime_error("Default Float data type must be one of [FLOAT8, FLOAT16, FLOAT32, DOUBLE]");
|
|
|
|
|
|
|
|
_dataType.store(dtype);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setVerbose(bool reallyVerbose) {
|
|
|
|
_verbose = reallyVerbose;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isDebug() {
|
|
|
|
return _debug.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isProfiling() {
|
|
|
|
return _profile.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isDetectingLeaks() {
|
|
|
|
return _leaks.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setLeaksDetector(bool reallyDetect) {
|
|
|
|
_leaks.store(reallyDetect);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setProfiling(bool reallyProfile) {
|
|
|
|
_profile.store(reallyProfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isDebugAndVerbose() {
|
|
|
|
return this->isDebug() && this->isVerbose();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setDebug(bool reallyDebug) {
|
|
|
|
_debug = reallyDebug;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Environment::tadThreshold() {
|
|
|
|
return _tadThreshold.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setTadThreshold(int threshold) {
|
|
|
|
_tadThreshold = threshold;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Environment::elementwiseThreshold() {
|
|
|
|
return _elementThreshold.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setElementwiseThreshold(int threshold) {
|
|
|
|
_elementThreshold = threshold;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Environment::maxThreads() {
|
|
|
|
return _maxThreads.load();
|
|
|
|
}
|
|
|
|
|
2019-11-14 12:35:02 +01:00
|
|
|
int Environment::maxMasterThreads() {
|
|
|
|
return _maxMasterThreads.load();
|
|
|
|
}
|
|
|
|
|
2019-06-06 14:21:15 +02:00
|
|
|
void Environment::setMaxThreads(int max) {
|
2019-11-14 12:35:02 +01:00
|
|
|
//_maxThreads.store(max);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::setMaxMasterThreads(int max) {
|
|
|
|
//_maxMasterThreads = max;
|
2019-06-06 14:21:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::precisionBoostAllowed() {
|
|
|
|
return _precBoost.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::allowPrecisionBoost(bool reallyAllow) {
|
|
|
|
_precBoost.store(reallyAllow);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Environment::isCPU() {
|
|
|
|
#ifdef __CUDABLAS__
|
|
|
|
return false;
|
|
|
|
#else
|
|
|
|
return true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-10-26 03:38:08 +02:00
|
|
|
int Environment::blasMajorVersion(){
|
|
|
|
return _blasMajorVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Environment::blasMinorVersion(){
|
|
|
|
return _blasMinorVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Environment::blasPatchVersion(){
|
|
|
|
return _blasPatchVersion;
|
|
|
|
}
|
|
|
|
|
2019-11-14 12:35:02 +01:00
|
|
|
bool Environment::helpersAllowed() {
|
|
|
|
return _allowHelpers.load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Environment::allowHelpers(bool reallyAllow) {
|
|
|
|
_allowHelpers.store(reallyAllow);
|
|
|
|
}
|
|
|
|
|
2019-06-06 14:21:15 +02:00
|
|
|
nd4j::Environment *nd4j::Environment::_instance = 0;
|
|
|
|
|
|
|
|
}
|