-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GPU] Added cl_context and compute engine information
Created enum LayerComputeEngine at layer.h API level Modified layer.h, factory.cpp, layer_node.h/cpp to propagate compute engine information Added cl_context to handle global configuration of OpenCL environment Modified RunLayerContext to enable getter/setter for compute engine Added kernel creation utility in RunLayerContext Used FullyConnected layer as example for propagating compute info Signed-off-by: Debadri Samaddar <[email protected]>
- Loading branch information
Showing
9 changed files
with
513 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
* @date 14 October 2020 | ||
* @see https://github.com/nnstreamer/nntrainer | ||
* @author Parichay Kapoor <[email protected]> | ||
* @author Debadri Samaddar <[email protected]> | ||
* @bug No known bugs except for NYI items | ||
* @brief This is layers interface for c++ API | ||
* | ||
|
@@ -100,6 +101,14 @@ enum LayerType { | |
LAYER_UNKNOWN = ML_TRAIN_LAYER_TYPE_UNKNOWN /**< Unknown */ | ||
}; | ||
|
||
/** | ||
* @brief Enumeration of layer compute engine | ||
*/ | ||
enum LayerComputeEngine { | ||
CPU, /**< CPU as the compute engine */ | ||
GPU, /**< GPU as the compute engine */ | ||
}; | ||
|
||
/** | ||
* @class Layer Base class for layers | ||
* @brief Base class for all layers | ||
|
@@ -239,7 +248,8 @@ class Layer { | |
*/ | ||
std::unique_ptr<Layer> | ||
createLayer(const LayerType &type, | ||
const std::vector<std::string> &properties = {}); | ||
const std::vector<std::string> &properties = {}, | ||
const LayerComputeEngine &compute_engine = LayerComputeEngine::CPU); | ||
|
||
/** | ||
* @brief Factory creator with constructor for layer | ||
|
@@ -279,9 +289,10 @@ Input(const std::vector<std::string> &properties = {}) { | |
/** | ||
* @brief Helper function to create fully connected layer | ||
*/ | ||
inline std::unique_ptr<Layer> | ||
FullyConnected(const std::vector<std::string> &properties = {}) { | ||
return createLayer(LayerType::LAYER_FC, properties); | ||
inline std::unique_ptr<Layer> FullyConnected( | ||
const std::vector<std::string> &properties = {}, | ||
const LayerComputeEngine &compute_engine = LayerComputeEngine::CPU) { | ||
return createLayer(LayerType::LAYER_FC, properties, compute_engine); | ||
} | ||
|
||
/** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
* @date 14 October 2020 | ||
* @see https://github.com/nnstreamer/nntrainer | ||
* @author Parichay Kapoor <[email protected]> | ||
* @author Debadri Samaddar <[email protected]> | ||
* @bug No known bugs except for NYI items | ||
* @brief This is implementaion for factory builder interface for c++ API | ||
*/ | ||
|
@@ -28,8 +29,9 @@ namespace ml { | |
namespace train { | ||
|
||
std::unique_ptr<Layer> createLayer(const LayerType &type, | ||
const std::vector<std::string> &properties) { | ||
return nntrainer::createLayerNode(type, properties); | ||
const std::vector<std::string> &properties, | ||
const LayerComputeEngine &compute_engine) { | ||
return nntrainer::createLayerNode(type, properties, compute_engine); | ||
} | ||
|
||
/** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
/** | ||
* Copyright (C) 2024 Debadri Samaddar <[email protected]> | ||
* | ||
* @file cl_context.h | ||
* @date 23 Feb 2024 | ||
* @see https://github.com/nnstreamer/nntrainer | ||
* @author Debadri Samaddar <[email protected]> | ||
* @bug No known bugs except for NYI items | ||
* @brief This file contains app context related functions and classes that | ||
* manages the global configuration of the current OpenCL environment. It also | ||
* creates the OpenCL command queue and context. | ||
*/ | ||
|
||
#include <cl_context.h> | ||
#include <fc_layer.h> | ||
|
||
namespace nntrainer { | ||
|
||
std::mutex cl_factory_mutex; | ||
|
||
std::once_flag global_cl_context_init_flag; | ||
|
||
static void add_default_object(ClContext &cc) { | ||
using LayerType = ml::train::LayerType; | ||
|
||
cc.registerFactory(nntrainer::createLayer<FullyConnectedLayer>, | ||
FullyConnectedLayer::type, LayerType::LAYER_FC); | ||
} | ||
|
||
static void registerer(ClContext &cc) noexcept { | ||
try { | ||
add_default_object(cc); | ||
} catch (std::exception &e) { | ||
ml_loge("cl_context: registering layers failed!!, reason: %s", e.what()); | ||
} catch (...) { | ||
ml_loge("cl_context: registering layer failed due to unknown reason"); | ||
} | ||
}; | ||
|
||
ClContext &ClContext::Global() { | ||
static ClContext instance; | ||
|
||
// initializing commandqueue and context | ||
bool result = instance.clInit(); | ||
|
||
if (!result) { | ||
ml_loge("cl_context: opencl command queue creation failed"); | ||
} | ||
|
||
/// in g++ there is a bug that hangs up if caller throws, | ||
/// so registerer is noexcept although it'd better not | ||
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70298 | ||
std::call_once(global_cl_context_init_flag, registerer, std::ref(instance)); | ||
return instance; | ||
} | ||
|
||
template <typename T> | ||
const int ClContext::registerFactory(const FactoryType<T> factory, | ||
const std::string &key, | ||
const int int_key) { | ||
static_assert(isSupported<T>::value, | ||
"cl_context: given type is not supported for current context"); | ||
|
||
auto &index = std::get<IndexType<T>>(factory_map); | ||
auto &str_map = std::get<StrIndexType<T>>(index); | ||
auto &int_map = std::get<IntIndexType>(index); | ||
|
||
std::string assigned_key = key == "" ? factory({})->getType() : key; | ||
|
||
std::transform(assigned_key.begin(), assigned_key.end(), assigned_key.begin(), | ||
[](unsigned char c) { return std::tolower(c); }); | ||
|
||
const std::lock_guard<std::mutex> lock(cl_factory_mutex); | ||
if (str_map.find(assigned_key) != str_map.end()) { | ||
std::stringstream ss; | ||
ss << "cl_context: cannot register factory with already taken key: " << key; | ||
throw std::invalid_argument(ss.str().c_str()); | ||
} | ||
|
||
if (int_key != -1 && int_map.find(int_key) != int_map.end()) { | ||
std::stringstream ss; | ||
ss << "cl_context: cannot register factory with already taken int key: " | ||
<< int_key; | ||
throw std::invalid_argument(ss.str().c_str()); | ||
} | ||
|
||
int assigned_int_key = int_key == -1 ? str_map.size() + 1 : int_key; | ||
|
||
str_map[assigned_key] = factory; | ||
int_map[assigned_int_key] = assigned_key; | ||
|
||
ml_logd("cl_context: factory has registered with key: %s, int_key: %d", | ||
assigned_key.c_str(), assigned_int_key); | ||
|
||
return assigned_int_key; | ||
} | ||
|
||
/** | ||
* @copydoc const int ClContext::registerFactory | ||
*/ | ||
template const int ClContext::registerFactory<nntrainer::Layer>( | ||
const FactoryType<nntrainer::Layer> factory, const std::string &key, | ||
const int int_key); | ||
|
||
} // namespace nntrainer |
Oops, something went wrong.