Code quality: Large clean-up of the codebase and especially of the include/ folder
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#include "isaac/array.h"
|
||||
#include "isaac/symbolic/execute.h"
|
||||
#include "isaac/tools/timer.hpp"
|
||||
#ifdef BENCH_CLBLAS
|
||||
#include "isaac/wrap/clBLAS.h"
|
||||
#endif
|
||||
@@ -16,6 +15,9 @@
|
||||
#include <numeric>
|
||||
#include <regex>
|
||||
|
||||
#include "timer.hpp"
|
||||
|
||||
|
||||
#define HAS_A_BLAS defined(BENCH_CBLAS) or defined(BENCH_CLBLAS) or defined(BENCH_CUBLAS)
|
||||
namespace isc = isaac;
|
||||
typedef isc::int_t int_t;
|
||||
|
41
include/isaac/common/expression_type.h
Normal file
41
include/isaac/common/expression_type.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef ISAAC_COMMON_EXPRESSION_TYPE_H
|
||||
#define ISAAC_COMMON_EXPRESSION_TYPE_H
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
enum expression_type
|
||||
{
|
||||
INVALID_EXPRESSION_TYPE,
|
||||
AXPY_TYPE,
|
||||
GER_TYPE,
|
||||
DOT_TYPE,
|
||||
GEMV_N_TYPE,
|
||||
GEMV_T_TYPE,
|
||||
GEMM_NN_TYPE,
|
||||
GEMM_TN_TYPE,
|
||||
GEMM_NT_TYPE,
|
||||
GEMM_TT_TYPE
|
||||
};
|
||||
|
||||
inline expression_type expression_type_from_string(std::string const & name)
|
||||
{
|
||||
if(name=="axpy") return AXPY_TYPE;
|
||||
if(name=="dot") return DOT_TYPE;
|
||||
if(name=="ger") return GER_TYPE;
|
||||
if(name=="gemv_n") return GEMV_N_TYPE;
|
||||
if(name=="gemv_t") return GEMV_T_TYPE;
|
||||
if(name=="gemm_nn") return GEMM_NN_TYPE;
|
||||
if(name=="gemm_nt") return GEMM_NT_TYPE;
|
||||
if(name=="gemm_tn") return GEMM_TN_TYPE;
|
||||
if(name=="gemm_tt") return GEMM_TT_TYPE;
|
||||
throw std::invalid_argument("Unrecognized expression: " + name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
104
include/isaac/common/numeric_type.h
Normal file
104
include/isaac/common/numeric_type.h
Normal file
@@ -0,0 +1,104 @@
|
||||
#ifndef ISAAC_COMMON_NUMERIC_TYPE_H
|
||||
#define ISAAC_COMMON_NUMERIC_TYPE_H
|
||||
|
||||
#include "isaac/exception/unknown_datatype.h"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
enum numeric_type
|
||||
{
|
||||
INVALID_NUMERIC_TYPE = 0,
|
||||
// BOOL_TYPE,
|
||||
CHAR_TYPE,
|
||||
UCHAR_TYPE,
|
||||
SHORT_TYPE,
|
||||
USHORT_TYPE,
|
||||
INT_TYPE,
|
||||
UINT_TYPE,
|
||||
LONG_TYPE,
|
||||
ULONG_TYPE,
|
||||
// HALF_TYPE,
|
||||
FLOAT_TYPE,
|
||||
DOUBLE_TYPE
|
||||
};
|
||||
|
||||
inline std::string to_string(numeric_type const & type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
// case BOOL_TYPE: return "bool";
|
||||
case CHAR_TYPE: return "char";
|
||||
case UCHAR_TYPE: return "uchar";
|
||||
case SHORT_TYPE: return "short";
|
||||
case USHORT_TYPE: return "ushort";
|
||||
case INT_TYPE: return "int";
|
||||
case UINT_TYPE: return "uint";
|
||||
case LONG_TYPE: return "long";
|
||||
case ULONG_TYPE: return "ulong";
|
||||
// case HALF_TYPE : return "half";
|
||||
case FLOAT_TYPE : return "float";
|
||||
case DOUBLE_TYPE : return "double";
|
||||
default : throw unknown_datatype(type);
|
||||
}
|
||||
}
|
||||
|
||||
inline numeric_type numeric_type_from_string(std::string const & name)
|
||||
{
|
||||
if(name=="float32") return FLOAT_TYPE;
|
||||
if(name=="float64") return DOUBLE_TYPE;
|
||||
throw std::invalid_argument("Invalid datatype: " + name);
|
||||
}
|
||||
|
||||
inline unsigned int size_of(numeric_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
// case BOOL_TYPE:
|
||||
case UCHAR_TYPE:
|
||||
case CHAR_TYPE: return 1;
|
||||
|
||||
// case HALF_TYPE:
|
||||
case USHORT_TYPE:
|
||||
case SHORT_TYPE: return 2;
|
||||
|
||||
case UINT_TYPE:
|
||||
case INT_TYPE:
|
||||
case FLOAT_TYPE: return 4;
|
||||
|
||||
case ULONG_TYPE:
|
||||
case LONG_TYPE:
|
||||
case DOUBLE_TYPE: return 8;
|
||||
|
||||
default: throw unknown_datatype(type);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t size, bool is_unsigned>
|
||||
struct to_int_numeric_type_impl;
|
||||
|
||||
#define ISAAC_INSTANTIATE_INT_TYPE_IMPL(SIZE, IS_UNSIGNED, TYPE) \
|
||||
template<> struct to_int_numeric_type_impl<SIZE, IS_UNSIGNED> { static const numeric_type value = TYPE; }
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(1, false, CHAR_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(2, false, SHORT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(4, false, INT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(8, false, LONG_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(1, true, UCHAR_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(2, true, USHORT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(4, true, UINT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(8, true, ULONG_TYPE);
|
||||
#undef ISAAC_INSTANTIATE_INT_TYPE_IMPL
|
||||
|
||||
template<class T>
|
||||
struct to_int_numeric_type
|
||||
{
|
||||
static const numeric_type value = to_int_numeric_type_impl<sizeof(T), std::is_unsigned<T>::value>::value;
|
||||
};
|
||||
|
||||
template<class T> struct to_numeric_type { static const numeric_type value = to_int_numeric_type<T>::value; };
|
||||
template<> struct to_numeric_type<float> { static const numeric_type value = FLOAT_TYPE; };
|
||||
template<> struct to_numeric_type<double> { static const numeric_type value = DOUBLE_TYPE; };
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -5,6 +5,9 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "isaac/common/expression_type.h"
|
||||
#include "isaac/common/numeric_type.h"
|
||||
|
||||
#include "isaac/driver/common.h"
|
||||
#include "isaac/defines.h"
|
||||
#include "isaac/types.h"
|
||||
|
@@ -20,9 +20,6 @@ class ISAACAPI Context
|
||||
friend class CommandQueue;
|
||||
friend class Buffer;
|
||||
|
||||
private:
|
||||
void init_cache_path();
|
||||
|
||||
public:
|
||||
explicit Context(cl_context const & context, bool take_ownership = true);
|
||||
explicit Context(Device const & device);
|
||||
|
@@ -20,7 +20,7 @@ private:
|
||||
friend class CommandQueue;
|
||||
|
||||
public:
|
||||
enum class ISAACAPI VENDOR
|
||||
enum class ISAACAPI Vendor
|
||||
{
|
||||
AMD,
|
||||
INTEL,
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
enum class ISAACAPI ARCHITECTURE
|
||||
enum class ISAACAPI Architecture
|
||||
{
|
||||
HASWELL,
|
||||
BROADWELL,
|
||||
@@ -49,8 +49,8 @@ public:
|
||||
bool operator==(Device const &) const;
|
||||
bool operator<(Device const &) const;
|
||||
|
||||
VENDOR vendor() const;
|
||||
ARCHITECTURE architecture() const;
|
||||
Vendor vendor() const;
|
||||
Architecture architecture() const;
|
||||
|
||||
backend_type backend() const;
|
||||
size_t clock_rate() const;
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include "isaac/kernels/parse.h"
|
||||
#include "isaac/kernels/stream.h"
|
||||
#include "isaac/symbolic/expression.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
@@ -115,41 +115,6 @@ protected:
|
||||
driver::Kernel & kernel_;
|
||||
};
|
||||
|
||||
struct loop_body_base
|
||||
{
|
||||
virtual void operator()(kernel_generation_stream & stream, unsigned int simd_width) const = 0;
|
||||
};
|
||||
|
||||
static void fetching_loop_info(fetching_policy_type policy, std::string const & bound, kernel_generation_stream & stream,
|
||||
std::string & init, std::string & upper_bound, std::string & inc, std::string const & domain_id, std::string const & domain_size, driver::Device const & device);
|
||||
|
||||
template<class Fun>
|
||||
static void element_wise_loop_1D(kernel_generation_stream & stream, fetching_policy_type fetch, unsigned int simd_width,
|
||||
std::string const & i, std::string const & bound, std::string const & domain_id, std::string const & domain_size, driver::Device const & device, Fun const & generate_body)
|
||||
{
|
||||
std::string strwidth = tools::to_string(simd_width);
|
||||
std::string boundround = bound + "/" + strwidth;
|
||||
|
||||
std::string init, upper_bound, inc;
|
||||
fetching_loop_info(fetch, boundround, stream, init, upper_bound, inc, domain_id, domain_size, device);
|
||||
stream << "for(unsigned int " << i << " = " << init << "; " << i << " < " << upper_bound << "; " << i << " += " << inc << ")" << std::endl;
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
generate_body(simd_width);
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
|
||||
if (simd_width>1)
|
||||
{
|
||||
stream << "for(unsigned int " << i << " = " << boundround << "*" << strwidth << " + " << domain_id << "; " << i << " < " << bound << "; " << i << " += " + domain_size + ")" << std::endl;
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
generate_body(1);
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void compute_dot(kernel_generation_stream & os, std::string acc, std::string cur, op_element const & op);
|
||||
static void compute_index_dot(kernel_generation_stream & os, std::string acc, std::string cur, std::string const & acc_value, std::string const & cur_value, op_element const & op);
|
||||
static void process_all(std::string const & type_key, std::string const & str, kernel_generation_stream & stream, std::vector<mapping_type> const & mappings);
|
||||
|
33
include/isaac/model/database.h
Normal file
33
include/isaac/model/database.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef ISAAC_MODEL_DATABASE_H
|
||||
#define ISAAC_MODEL_DATABASE_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "isaac/driver/command_queue.h"
|
||||
#include "isaac/driver/device.h"
|
||||
#include "isaac/common/expression_type.h"
|
||||
#include "isaac/common/numeric_type.h"
|
||||
#include "isaac/model/model.h"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
struct database
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::pair<expression_type, numeric_type>, std::shared_ptr<model> > map_type;
|
||||
private:
|
||||
static void import(std::string const & fname, driver::CommandQueue const & queue);
|
||||
static map_type & init(driver::CommandQueue const & queue);
|
||||
public:
|
||||
static map_type & get(driver::CommandQueue const & queue);
|
||||
static void set(driver::CommandQueue const & queue, expression_type operation, numeric_type dtype, std::shared_ptr<model> const & model);
|
||||
private:
|
||||
static const std::map<std::tuple<driver::Device::Vendor, driver::Device::Architecture> , const char *> presets_;
|
||||
static std::map<driver::CommandQueue, map_type> cache_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -38,21 +38,6 @@ namespace isaac
|
||||
driver::ProgramCache & cache_;
|
||||
};
|
||||
|
||||
class models
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::pair<expression_type, numeric_type>, std::shared_ptr<model> > map_type;
|
||||
private:
|
||||
static void import(std::string const & fname, driver::CommandQueue const & queue);
|
||||
static map_type & init(driver::CommandQueue const & queue);
|
||||
public:
|
||||
static map_type & get(driver::CommandQueue const & queue);
|
||||
static void set(driver::CommandQueue const & queue, expression_type operation, numeric_type dtype, std::shared_ptr<model> const & model);
|
||||
private:
|
||||
static std::map<driver::CommandQueue, map_type> data_;
|
||||
static const std::map<std::pair<driver::Device::VENDOR, driver::Device::ARCHITECTURE> , const char *> database_;
|
||||
};
|
||||
|
||||
extern std::map<std::pair<expression_type, numeric_type>, std::shared_ptr<templates::base> > fallbacks;
|
||||
|
||||
}
|
||||
|
@@ -1,14 +1,14 @@
|
||||
#ifndef _ISAAC_SCHEDULER_EXECUTE_H
|
||||
#define _ISAAC_SCHEDULER_EXECUTE_H
|
||||
|
||||
#include "isaac/model/model.h"
|
||||
#include "isaac/model/database.h"
|
||||
#include "isaac/symbolic/expression.h"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
/** @brief Executes a array_expression on the given queue for the given models map*/
|
||||
void execute(controller<array_expression> const & , models::map_type &);
|
||||
void execute(controller<array_expression> const & , database::map_type &);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -1,41 +0,0 @@
|
||||
#ifndef ISAAC_TOOLS_MAKE_MAP_HPP
|
||||
#define ISAAC_TOOLS_MAKE_MAP_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template<typename MapT>
|
||||
class make_map
|
||||
{
|
||||
typedef typename MapT::key_type T;
|
||||
typedef typename MapT::mapped_type U;
|
||||
public:
|
||||
make_map(const T& key, const U& val)
|
||||
{
|
||||
map_.insert(std::make_pair(key,val));
|
||||
}
|
||||
|
||||
make_map<MapT>& operator()(const T& key, const U& val)
|
||||
{
|
||||
map_.insert(std::make_pair(key,val));
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator MapT()
|
||||
{
|
||||
return map_;
|
||||
}
|
||||
private:
|
||||
MapT map_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,32 +0,0 @@
|
||||
#ifndef ISAAC_TOOLS_MAKE_VECTOR_HPP
|
||||
#define ISAAC_TOOLS_MAKE_VECTOR_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class make_vector
|
||||
{
|
||||
public:
|
||||
typedef make_vector<T> my_type;
|
||||
my_type& operator<< (const T& val) {
|
||||
data_.push_back(val);
|
||||
return *this;
|
||||
}
|
||||
operator std::vector<T>() const {
|
||||
return data_;
|
||||
}
|
||||
private:
|
||||
std::vector<T> data_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,122 +0,0 @@
|
||||
/* =========================================================================
|
||||
Copyright (c) 2010-2014, Institute for Microelectronics,
|
||||
Institute for Analysis and Scientific Computing,
|
||||
TU Wien.
|
||||
Portions of this software are copyright by UChicago Argonne, LLC.
|
||||
|
||||
-----------------
|
||||
ViennaCL - The Vienna Computing Library
|
||||
-----------------
|
||||
|
||||
Project Head: Karl Rupp rupp@iue.tuwien.ac.at
|
||||
|
||||
(A list of authors and contributors can be found in the PDF manual)
|
||||
|
||||
License: MIT (X11), see file LICENSE in the base directory
|
||||
============================================================================= */
|
||||
|
||||
#ifndef _ISAAC_TOOLS_TIMER_HPP_
|
||||
#define _ISAAC_TOOLS_TIMER_HPP_
|
||||
|
||||
/** @file isaac/tools/timer.hpp
|
||||
@brief A simple, yet (mostly) sufficiently accurate timer for benchmarking and profiling. */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
/** @brief Simple timer class based on gettimeofday (POSIX) or QueryPerformanceCounter (Windows).
|
||||
*
|
||||
* Avoids messing with Boost and should be sufficient for benchmarking purposes.
|
||||
*/
|
||||
class timer
|
||||
{
|
||||
public:
|
||||
|
||||
timer()
|
||||
{
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &start_time);
|
||||
}
|
||||
|
||||
double get() const
|
||||
{
|
||||
LARGE_INTEGER elapsed;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &end_time);
|
||||
elapsed.QuadPart = end_time.QuadPart - start_time.QuadPart;
|
||||
return elapsed.QuadPart / static_cast<double>(freq.QuadPart);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LARGE_INTEGER freq;
|
||||
LARGE_INTEGER start_time;
|
||||
LARGE_INTEGER end_time;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
/** @brief Simple timer class based on gettimeofday (POSIX) or QueryPerformanceCounter (Windows).
|
||||
*
|
||||
* Avoids messing with Boost and should be sufficient for benchmarking purposes.
|
||||
*/
|
||||
class timer
|
||||
{
|
||||
public:
|
||||
|
||||
timer() : ts(0)
|
||||
{}
|
||||
|
||||
void start()
|
||||
{
|
||||
struct timeval tval;
|
||||
gettimeofday(&tval, NULL);
|
||||
ts = static_cast<double>(tval.tv_sec * 1000000 + tval.tv_usec);
|
||||
}
|
||||
|
||||
double get() const
|
||||
{
|
||||
struct timeval tval;
|
||||
gettimeofday(&tval, NULL);
|
||||
double end_time = static_cast<double>(tval.tv_sec * 1000000 + tval.tv_usec);
|
||||
|
||||
return static_cast<double>(end_time-ts) / 1000000.0;
|
||||
}
|
||||
|
||||
private:
|
||||
double ts;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
@@ -2,8 +2,8 @@
|
||||
#define ISAAC_TYPES_H
|
||||
|
||||
#include <list>
|
||||
#include <cstddef>
|
||||
#include "isaac/defines.h"
|
||||
#include "isaac/exception/unknown_datatype.h"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
@@ -37,106 +37,6 @@ struct repeat_infos
|
||||
int_t rep2;
|
||||
};
|
||||
|
||||
|
||||
enum numeric_type
|
||||
{
|
||||
INVALID_NUMERIC_TYPE = 0,
|
||||
// BOOL_TYPE,
|
||||
CHAR_TYPE,
|
||||
UCHAR_TYPE,
|
||||
SHORT_TYPE,
|
||||
USHORT_TYPE,
|
||||
INT_TYPE,
|
||||
UINT_TYPE,
|
||||
LONG_TYPE,
|
||||
ULONG_TYPE,
|
||||
// HALF_TYPE,
|
||||
FLOAT_TYPE,
|
||||
DOUBLE_TYPE
|
||||
};
|
||||
|
||||
inline std::string numeric_type_to_string(numeric_type const & type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
// case BOOL_TYPE: return "bool";
|
||||
case CHAR_TYPE: return "char";
|
||||
case UCHAR_TYPE: return "uchar";
|
||||
case SHORT_TYPE: return "short";
|
||||
case USHORT_TYPE: return "ushort";
|
||||
case INT_TYPE: return "int";
|
||||
case UINT_TYPE: return "uint";
|
||||
case LONG_TYPE: return "long";
|
||||
case ULONG_TYPE: return "ulong";
|
||||
// case HALF_TYPE : return "half";
|
||||
case FLOAT_TYPE : return "float";
|
||||
case DOUBLE_TYPE : return "double";
|
||||
default : throw unknown_datatype(type);
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned int size_of(numeric_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
// case BOOL_TYPE:
|
||||
case UCHAR_TYPE:
|
||||
case CHAR_TYPE: return 1;
|
||||
|
||||
// case HALF_TYPE:
|
||||
case USHORT_TYPE:
|
||||
case SHORT_TYPE: return 2;
|
||||
|
||||
case UINT_TYPE:
|
||||
case INT_TYPE:
|
||||
case FLOAT_TYPE: return 4;
|
||||
|
||||
case ULONG_TYPE:
|
||||
case LONG_TYPE:
|
||||
case DOUBLE_TYPE: return 8;
|
||||
|
||||
default: throw unknown_datatype(type);
|
||||
}
|
||||
}
|
||||
|
||||
template<size_t size, bool is_unsigned>
|
||||
struct to_int_numeric_type_impl;
|
||||
|
||||
#define ISAAC_INSTANTIATE_INT_TYPE_IMPL(SIZE, IS_UNSIGNED, TYPE) \
|
||||
template<> struct to_int_numeric_type_impl<SIZE, IS_UNSIGNED> { static const numeric_type value = TYPE; }
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(1, false, CHAR_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(2, false, SHORT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(4, false, INT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(8, false, LONG_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(1, true, UCHAR_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(2, true, USHORT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(4, true, UINT_TYPE);
|
||||
ISAAC_INSTANTIATE_INT_TYPE_IMPL(8, true, ULONG_TYPE);
|
||||
#undef ISAAC_INSTANTIATE_INT_TYPE_IMPL
|
||||
|
||||
template<class T>
|
||||
struct to_int_numeric_type
|
||||
{ static const numeric_type value = to_int_numeric_type_impl<sizeof(T), std::is_unsigned<T>::value>::value; };
|
||||
|
||||
template<class T> struct to_numeric_type { static const numeric_type value = to_int_numeric_type<T>::value; };
|
||||
template<> struct to_numeric_type<float> { static const numeric_type value = FLOAT_TYPE; };
|
||||
template<> struct to_numeric_type<double> { static const numeric_type value = DOUBLE_TYPE; };
|
||||
|
||||
|
||||
enum expression_type
|
||||
{
|
||||
INVALID_EXPRESSION_TYPE,
|
||||
AXPY_TYPE,
|
||||
GER_TYPE,
|
||||
DOT_TYPE,
|
||||
GEMV_N_TYPE,
|
||||
GEMV_T_TYPE,
|
||||
GEMM_NN_TYPE,
|
||||
GEMM_TN_TYPE,
|
||||
GEMM_NT_TYPE,
|
||||
GEMM_TT_TYPE
|
||||
};
|
||||
|
||||
struct slice
|
||||
{
|
||||
slice(int_t _start, int_t _end, int_t _stride = 1) : start(_start), size((_end - _start)/_stride), stride(_stride) { }
|
||||
|
@@ -1,10 +1,11 @@
|
||||
#Database
|
||||
set(DATABASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/model/database/")
|
||||
set(DATABASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/model/presets/")
|
||||
file(GLOB_RECURSE JSON_FILES "${DATABASE_PATH}/json/*.json")
|
||||
CODE_TO_H(SOURCES ${JSON_FILES} VARNAME json_files EXTENSION "hpp" OUTPUT_DIR "${DATABASE_PATH}"
|
||||
NAMESPACE "isaac database" TARGET database EOF "0")
|
||||
NAMESPACE "isaac presets" TARGET database EOF "0")
|
||||
|
||||
#Compilation
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/tools")
|
||||
if(ANDROID)
|
||||
add_library(isaac STATIC ${LIBISAAC_SRC})
|
||||
else()
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "isaac/array.h"
|
||||
#include "isaac/exception/unknown_datatype.h"
|
||||
#include "isaac/model/model.h"
|
||||
#include "isaac/model/database.h"
|
||||
#include "isaac/symbolic/execute.h"
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ array& array::operator=(controller<TYPE> const & c)
|
||||
assert(dtype_ == c.x().dtype());
|
||||
array_expression expression(*this, c.x(), op_element(OPERATOR_BINARY_TYPE_FAMILY, OPERATOR_ASSIGN_TYPE), context_, dtype_, shape_);
|
||||
execute(controller<array_expression>(expression, c.execution_options(), c.dispatcher_options(), c.compilation_options()),
|
||||
isaac::models::get(c.execution_options().queue(context_)));
|
||||
isaac::database::get(c.execution_options().queue(context_)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,10 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "isaac/driver/context.h"
|
||||
#include "helpers/ocl/infos.hpp"
|
||||
#include "isaac/driver/program.h"
|
||||
#include "isaac/tools/getenv.hpp"
|
||||
|
||||
#include "helpers/ocl/infos.hpp"
|
||||
#include "getenv.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
@@ -10,32 +12,13 @@ namespace isaac
|
||||
namespace driver
|
||||
{
|
||||
|
||||
void Context::init_cache_path()
|
||||
{
|
||||
#ifndef ANDROID
|
||||
#ifdef _MSC_VER
|
||||
char* cache_path = 0;
|
||||
std::size_t sz = 0;
|
||||
_dupenv_s(&cache_path, &sz, "ISAAC_CACHE_PATH");
|
||||
#else
|
||||
const char * cache_path = std::getenv("ISAAC_CACHE_PATH");
|
||||
#endif
|
||||
if (cache_path)
|
||||
cache_path_ = cache_path;
|
||||
else
|
||||
#endif
|
||||
cache_path_ = "";
|
||||
}
|
||||
|
||||
Context::Context(cl_context const & context, bool take_ownership) : backend_(OPENCL), device_(ocl::info<CL_CONTEXT_DEVICES>(context)[0], false), cache_path_(tools::getenv("ISAAC_CACHE_PATH")), h_(backend_, take_ownership)
|
||||
{
|
||||
init_cache_path();
|
||||
h_.cl() = context;
|
||||
}
|
||||
|
||||
Context::Context(Device const & device) : backend_(device.backend_), device_(device), cache_path_(tools::getenv("ISAAC_CACHE_PATH")), h_(backend_, true)
|
||||
{
|
||||
init_cache_path();
|
||||
switch(backend_)
|
||||
{
|
||||
#ifdef ISAAC_WITH_CUDA
|
||||
|
@@ -40,31 +40,31 @@ bool Device::operator<(Device const & other) const
|
||||
|
||||
|
||||
|
||||
Device::VENDOR Device::vendor() const
|
||||
Device::Vendor Device::vendor() const
|
||||
{
|
||||
std::string vname = vendor_str();
|
||||
std::transform(vname.begin(), vname.end(), vname.begin(), ::tolower);
|
||||
if(vname.find("nvidia")!=std::string::npos)
|
||||
return VENDOR::NVIDIA;
|
||||
return Vendor::NVIDIA;
|
||||
else if(vname.find("intel")!=std::string::npos)
|
||||
return VENDOR::INTEL;
|
||||
return Vendor::INTEL;
|
||||
else if(vname.find("amd")!=std::string::npos || vname.find("advanced micro devices")!=std::string::npos)
|
||||
return VENDOR::AMD;
|
||||
return Vendor::AMD;
|
||||
else
|
||||
return VENDOR::UNKNOWN;
|
||||
return Vendor::UNKNOWN;
|
||||
}
|
||||
|
||||
Device::ARCHITECTURE Device::architecture() const
|
||||
Device::Architecture Device::architecture() const
|
||||
{
|
||||
switch(vendor())
|
||||
{
|
||||
case VENDOR::INTEL:
|
||||
case Vendor::INTEL:
|
||||
{
|
||||
return ARCHITECTURE::BROADWELL;
|
||||
return Architecture::BROADWELL;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return ARCHITECTURE::UNKNOWN;
|
||||
return Architecture::UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
#include "isaac/driver/platform.h"
|
||||
#include "isaac/driver/device.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
|
||||
#include "helpers/ocl/infos.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
|
@@ -3,13 +3,14 @@
|
||||
|
||||
#include "isaac/driver/program.h"
|
||||
#include "isaac/driver/context.h"
|
||||
#include "isaac/tools/sha1.hpp"
|
||||
|
||||
#ifdef ISAAC_WITH_CUDA
|
||||
#include "helpers/cuda/vector.hpp"
|
||||
#endif
|
||||
#include "helpers/ocl/infos.hpp"
|
||||
|
||||
#include "sha1.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "isaac/exception/unknown_datatype.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
@@ -7,8 +7,9 @@
|
||||
#include "isaac/kernels/parse.h"
|
||||
#include "isaac/kernels/stream.h"
|
||||
#include "isaac/symbolic/expression.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
#include "isaac/tools/find_and_replace.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
#include "find_and_replace.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
@@ -1,12 +1,14 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
#include "isaac/kernels/templates/axpy.h"
|
||||
#include "isaac/kernels/keywords.h"
|
||||
#include "isaac/driver/backend.h"
|
||||
#include "isaac/tools/make_map.hpp"
|
||||
#include "isaac/tools/make_vector.hpp"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#include "tools/loop.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
@@ -83,7 +85,7 @@ std::string axpy::generate_impl(std::string const & suffix, expressions_tuple co
|
||||
stream << "if(idx==0)" << std::endl;
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
process(stream, LHS_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array0", "#pointer[#start] = #namereg;"), expressions, mappings);
|
||||
process(stream, LHS_NODE_TYPE, { {"array0", "#pointer[#start] = #namereg;"} }, expressions, mappings);
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
|
||||
@@ -107,7 +109,7 @@ axpy::axpy(unsigned int simd, unsigned int ls, unsigned int ng,
|
||||
std::vector<int_t> axpy::input_sizes(expressions_tuple const & expressions) const
|
||||
{
|
||||
size4 shape = static_cast<array_expression const *>(expressions.data().front().get())->shape();
|
||||
return tools::make_vector<int_t>() << std::max(shape[0], shape[1]);
|
||||
return {std::max(shape[0], shape[1])};
|
||||
}
|
||||
|
||||
void axpy::enqueue(driver::CommandQueue & queue, driver::Program const & program, std::string const & suffix, base & fallback, controller<expressions_tuple> const & controller)
|
||||
|
@@ -12,10 +12,10 @@
|
||||
#include "isaac/kernels/parse.h"
|
||||
#include "isaac/exception/operation_not_supported.h"
|
||||
#include "isaac/exception/unknown_datatype.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
#include "isaac/tools/make_map.hpp"
|
||||
#include "isaac/symbolic/io.h"
|
||||
|
||||
#include "to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace templates
|
||||
@@ -36,20 +36,20 @@ numeric_type base::map_functor::get_numeric_type(isaac::array_expression const *
|
||||
template<class T>
|
||||
std::shared_ptr<mapped_object> base::map_functor::binary_leaf(isaac::array_expression const * array_expression, int_t root_idx, mapping_type const * mapping) const
|
||||
{
|
||||
return std::shared_ptr<mapped_object>(new T(numeric_type_to_string(array_expression->dtype()), binder_.get(), mapped_object::node_info(mapping, array_expression, root_idx)));
|
||||
return std::shared_ptr<mapped_object>(new T(to_string(array_expression->dtype()), binder_.get(), mapped_object::node_info(mapping, array_expression, root_idx)));
|
||||
}
|
||||
|
||||
/** @brief Scalar mapping */
|
||||
std::shared_ptr<mapped_object> base::map_functor::create(numeric_type dtype, values_holder) const
|
||||
{
|
||||
std::string strdtype = numeric_type_to_string(dtype);
|
||||
std::string strdtype = to_string(dtype);
|
||||
return std::shared_ptr<mapped_object>(new mapped_host_scalar(strdtype, binder_.get()));
|
||||
}
|
||||
|
||||
/** @brief Vector mapping */
|
||||
std::shared_ptr<mapped_object> base::map_functor::create(array const * a) const
|
||||
{
|
||||
std::string dtype = numeric_type_to_string(a->dtype());
|
||||
std::string dtype = to_string(a->dtype());
|
||||
unsigned int id = binder_.get(a->data());
|
||||
//Scalar
|
||||
if(a->shape()[0]==1 && a->shape()[1]==1)
|
||||
@@ -279,11 +279,12 @@ std::string base::generate_arguments(std::string const & data_type, driver::Devi
|
||||
{
|
||||
std::string kwglobal = Global(device.backend()).get();
|
||||
std::string _size_t = size_type(device);
|
||||
return generate_arguments(mappings, tools::make_map<std::map<std::string, std::string> >("array0", kwglobal + " #scalartype* #pointer, " + _size_t + " #start,")
|
||||
("host_scalar", "#scalartype #name,")
|
||||
("array1", kwglobal + " " + data_type + "* #pointer, " + _size_t + " #start, " + _size_t + " #stride,")
|
||||
("array2", kwglobal + " " + data_type + "* #pointer, " + _size_t + " #ld, " + _size_t + " #start1, " + _size_t + " #start2, " + _size_t + " #stride1, " + _size_t + " #stride2,")
|
||||
("tuple4", "#scalartype #name0, #scalartype #name1, #scalartype #name2, #scalartype #name3,"), expressions);
|
||||
return generate_arguments(mappings, { {"array0", kwglobal + " #scalartype* #pointer, " + _size_t + " #start,"},
|
||||
{"host_scalar", "#scalartype #name,"},
|
||||
{"array1", kwglobal + " " + data_type + "* #pointer, " + _size_t + " #start, " + _size_t + " #stride,"},
|
||||
{"array2", kwglobal + " " + data_type + "* #pointer, " + _size_t + " #ld, " + _size_t + " #start1, " + _size_t + " #start2, " + _size_t + " #stride1, " + _size_t + " #stride2,"},
|
||||
{"tuple4", "#scalartype #name0, #scalartype #name1, #scalartype #name2, #scalartype #name3,"}}
|
||||
, expressions);
|
||||
}
|
||||
|
||||
|
||||
@@ -306,30 +307,6 @@ const char* base::invalid_exception::what() const throw() { return message_.c_st
|
||||
|
||||
base::invalid_exception::~invalid_exception() throw() {}
|
||||
|
||||
void base::fetching_loop_info(fetching_policy_type policy, std::string const & bound, kernel_generation_stream & stream, std::string & init, std::string & upper_bound, std::string & inc, std::string const & domain_id, std::string const & domain_size, driver::Device const & device)
|
||||
{
|
||||
if (policy==FETCH_FROM_GLOBAL_STRIDED)
|
||||
{
|
||||
init = domain_id;
|
||||
upper_bound = bound;
|
||||
inc = domain_size;
|
||||
}
|
||||
else if (policy==FETCH_FROM_GLOBAL_CONTIGUOUS)
|
||||
{
|
||||
std::string _size_t = size_type(device);
|
||||
std::string chunk_size = "chunk_size";
|
||||
std::string chunk_start = "chunk_start";
|
||||
std::string chunk_end = "chunk_end";
|
||||
|
||||
stream << _size_t << " " << chunk_size << " = (" << bound << "+" << domain_size << "-1)/" << domain_size << ";" << std::endl;
|
||||
stream << _size_t << " " << chunk_start << " =" << domain_id << "*" << chunk_size << ";" << std::endl;
|
||||
stream << _size_t << " " << chunk_end << " = min(" << chunk_start << "+" << chunk_size << ", " << bound << ");" << std::endl;
|
||||
init = chunk_start;
|
||||
upper_bound = chunk_end;
|
||||
inc = "1";
|
||||
}
|
||||
}
|
||||
|
||||
bool base::is_node_trans(array_expression::container_type const & array, size_t root_idx, leaf_t leaf_type)
|
||||
{
|
||||
bool res = false;
|
||||
|
@@ -1,10 +1,12 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "isaac/kernels/templates/dot.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
#include "isaac/tools/make_map.hpp"
|
||||
#include "isaac/tools/make_vector.hpp"
|
||||
#include "isaac/kernels/keywords.h"
|
||||
|
||||
#include "tools/loop.hpp"
|
||||
#include "to_string.hpp"
|
||||
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace templates
|
||||
@@ -73,7 +75,7 @@ std::string dot::generate_impl(std::string const & suffix, expressions_tuple con
|
||||
std::string arguments = _size_t + " N, ";
|
||||
for (unsigned int k = 0; k < N; ++k)
|
||||
{
|
||||
std::string numeric_type = numeric_type_to_string(lhs_most(exprs[k]->array_expression().tree(), exprs[k]->array_expression().root()).lhs.dtype);
|
||||
std::string numeric_type = to_string(lhs_most(exprs[k]->array_expression().tree(), exprs[k]->array_expression().root()).lhs.dtype);
|
||||
if (exprs[k]->is_index_dot())
|
||||
{
|
||||
arguments += exprs[k]->process(Global(backend).get() + " unsigned int* #name_temp, ");
|
||||
@@ -276,7 +278,7 @@ std::vector<int_t> dot::input_sizes(expressions_tuple const & expressions) const
|
||||
{
|
||||
std::vector<size_t> dots_idx = filter_nodes(&is_dot, *(expressions.data().front()), false);
|
||||
int_t N = vector_size(lhs_most(expressions.data().front()->tree(), dots_idx[0]));
|
||||
return tools::make_vector<int_t>() << N;
|
||||
return {N};
|
||||
}
|
||||
|
||||
void dot::enqueue(driver::CommandQueue & queue, driver::Program const & program, std::string const & suffix, base & fallback, controller<expressions_tuple> const & controller)
|
||||
|
@@ -4,9 +4,9 @@
|
||||
#include "isaac/model/model.h"
|
||||
#include "isaac/symbolic/preset.h"
|
||||
#include "isaac/exception/operation_not_supported.h"
|
||||
#include "isaac/tools/make_vector.hpp"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
#include "isaac/tools/miscellaneous.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
#include "align.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
@@ -118,7 +118,7 @@ gemm_parameters::gemm_parameters(unsigned int simd_width
|
||||
kernel_generation_stream stream;
|
||||
array_expression const & st = (*expressions.data().front());
|
||||
numeric_type dtype = lhs_most(st.tree(), st.root()).lhs.dtype;
|
||||
std::string sdtype = numeric_type_to_string(dtype);
|
||||
std::string sdtype = to_string(dtype);
|
||||
std::string vdtype = append_width(sdtype, p_.simd_width);
|
||||
std::string _size_t = size_type(device);
|
||||
std::string vint = append_width("int", p_.simd_width);
|
||||
|
@@ -3,9 +3,10 @@
|
||||
#include "isaac/kernels/stream.h"
|
||||
#include "isaac/kernels/keywords.h"
|
||||
#include "isaac/kernels/templates/gemv.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
#include "isaac/tools/make_map.hpp"
|
||||
#include "isaac/tools/make_vector.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
|
||||
#include "tools/loop.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
@@ -59,7 +60,7 @@ std::string gemv::generate_impl(std::string const & suffix, expressions_tuple co
|
||||
std::string arguments = _size_t + " M, " + _size_t + " N, " ;
|
||||
for (const auto & e : dots)
|
||||
{
|
||||
std::string numeric_type = numeric_type_to_string(lhs_most(e->array_expression().tree(), e->array_expression().root()).lhs.dtype);
|
||||
std::string numeric_type = to_string(lhs_most(e->array_expression().tree(), e->array_expression().root()).lhs.dtype);
|
||||
if (e->is_index_dot())
|
||||
{
|
||||
arguments += e->process(Global(backend).get() + " unsigned int* #name_temp, ");
|
||||
@@ -333,7 +334,7 @@ std::vector<int_t> gemv::input_sizes(expressions_tuple const & expressions) cons
|
||||
std::pair<int_t, int_t> MN = matrix_size(lhs_most(first_expression.tree(), idx[0]));
|
||||
if(dot_type_==REDUCE_COLUMNS)
|
||||
std::swap(MN.first,MN.second);
|
||||
return tools::make_vector<int_t>() << MN.first << MN.second;
|
||||
return {MN.first, MN.second};
|
||||
}
|
||||
|
||||
void gemv::enqueue(driver::CommandQueue & queue, driver::Program const & program, std::string const & suffix, base & fallback, controller<expressions_tuple> const & controller)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "isaac/kernels/templates/ger.h"
|
||||
#include "isaac/tools/make_map.hpp"
|
||||
#include "isaac/tools/make_vector.hpp"
|
||||
#include "isaac/symbolic/io.h"
|
||||
#include "isaac/kernels/keywords.h"
|
||||
|
||||
#include "tools/loop.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace templates
|
||||
@@ -47,9 +47,10 @@ std::string ger::generate_impl(std::string const & suffix, expressions_tuple con
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
|
||||
process(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array0", "#scalartype #namereg = #pointer[#start];")
|
||||
("array1", "#pointer += #start;")
|
||||
("array2", "#pointer = &$VALUE{#start1, #start2};"), expressions, mappings);
|
||||
process(stream, PARENT_NODE_TYPE, { {"array0", "#scalartype #namereg = #pointer[#start];"},
|
||||
{"array1", "#pointer += #start;"},
|
||||
{"array2", "#pointer = &$VALUE{#start1, #start2};"}}
|
||||
, expressions, mappings);
|
||||
|
||||
fetching_loop_info(p_.fetching_policy, "M", stream, init0, upper_bound0, inc0, GlobalIdx0(backend).get(), GlobalSize0(backend).get(), device);
|
||||
stream << "for(" << _size_t << " i = " << init0 << "; i < " << upper_bound0 << "; i += " << inc0 << ")" << std::endl;
|
||||
@@ -60,25 +61,22 @@ std::string ger::generate_impl(std::string const & suffix, expressions_tuple con
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
|
||||
process(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >
|
||||
("array2", data_type + " #namereg = $VALUE{i*#stride1,j*#stride2};")
|
||||
("vdiag", "#scalartype #namereg = ((i + ((#diag_offset<0)?#diag_offset:0))!=(j-((#diag_offset>0)?#diag_offset:0)))?0:$VALUE{min(i*#stride1, j*#stride1)};")
|
||||
("repeat", "#scalartype #namereg = $VALUE{(i%#tuplearg0)*#stride1, (j%#tuplearg1)*#stride2};")
|
||||
("outer", "#scalartype #namereg = ($LVALUE{i*#stride})*($RVALUE{j*#stride});")
|
||||
process(stream, PARENT_NODE_TYPE, { {"array2", data_type + " #namereg = $VALUE{i*#stride1,j*#stride2};"},
|
||||
{"vdiag", "#scalartype #namereg = ((i + ((#diag_offset<0)?#diag_offset:0))!=(j-((#diag_offset>0)?#diag_offset:0)))?0:$VALUE{min(i*#stride1, j*#stride1)};"},
|
||||
{"repeat", "#scalartype #namereg = $VALUE{(i%#tuplearg0)*#stride1, (j%#tuplearg1)*#stride2};"},
|
||||
{"outer", "#scalartype #namereg = ($LVALUE{i*#stride})*($RVALUE{j*#stride});"} }
|
||||
, expressions, mappings);
|
||||
|
||||
evaluate(stream, PARENT_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >
|
||||
("array2", "#namereg")
|
||||
("vdiag", "#namereg")
|
||||
("repeat", "#namereg")
|
||||
("array0", "#namereg")
|
||||
("outer", "#namereg")
|
||||
("cast", CastPrefix(backend, data_type).get())
|
||||
("host_scalar", p_.simd_width==1?"#name": InitPrefix(backend, data_type).get() + "(#name)")
|
||||
evaluate(stream, PARENT_NODE_TYPE, { {"array2", "#namereg"},
|
||||
{"vdiag", "#namereg"},
|
||||
{"repeat", "#namereg"},
|
||||
{"array0", "#namereg"},
|
||||
{"outer", "#namereg"},
|
||||
{"cast", CastPrefix(backend, data_type).get()},
|
||||
{"host_scalar", p_.simd_width==1?"#name": InitPrefix(backend, data_type).get() + "(#name)"}}
|
||||
, expressions, mappings);
|
||||
|
||||
process(stream, LHS_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array2", "$VALUE{i*#stride1,j*#stride2} = #namereg;")
|
||||
, expressions, mappings);
|
||||
process(stream, LHS_NODE_TYPE, { {"array2", "$VALUE{i*#stride1,j*#stride2} = #namereg;"} } , expressions, mappings);
|
||||
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
@@ -88,7 +86,7 @@ std::string ger::generate_impl(std::string const & suffix, expressions_tuple con
|
||||
stream << "if(" << GlobalIdx0(backend) << "==0 &&" << GlobalIdx1(backend) << "==0)" << std::endl;
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
process(stream, LHS_NODE_TYPE, tools::make_map<std::map<std::string, std::string> >("array0", "#pointer[#start] = #namereg;"), expressions, mappings);
|
||||
process(stream, LHS_NODE_TYPE, { {"array0", "#pointer[#start] = #namereg;"} }, expressions, mappings);
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
|
||||
@@ -111,7 +109,7 @@ std::vector<int_t> ger::input_sizes(expressions_tuple const & expressions) const
|
||||
{
|
||||
isaac::array_expression const & array_expression = *(expressions.data().front());
|
||||
std::pair<int_t, int_t> size = matrix_size(lhs_most(array_expression.tree(), array_expression.root()));
|
||||
return tools::make_vector<int_t>() << size.first << size.second;
|
||||
return {size.first, size.second};
|
||||
}
|
||||
|
||||
void ger::enqueue(driver::CommandQueue & /*queue*/, driver::Program const & program, std::string const & suffix, base &, controller<expressions_tuple> const & controller)
|
||||
|
64
lib/kernels/templates/tools/loop.hpp
Normal file
64
lib/kernels/templates/tools/loop.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "isaac/kernels/stream.h"
|
||||
#include "isaac/kernels/templates/base.h"
|
||||
#include <string>
|
||||
#include "to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace templates
|
||||
{
|
||||
|
||||
inline void fetching_loop_info(fetching_policy_type policy, std::string const & bound, kernel_generation_stream & stream, std::string & init, std::string & upper_bound, std::string & inc, std::string const & domain_id, std::string const & domain_size, driver::Device const & device)
|
||||
{
|
||||
if (policy==FETCH_FROM_GLOBAL_STRIDED)
|
||||
{
|
||||
init = domain_id;
|
||||
upper_bound = bound;
|
||||
inc = domain_size;
|
||||
}
|
||||
else if (policy==FETCH_FROM_GLOBAL_CONTIGUOUS)
|
||||
{
|
||||
std::string _size_t = size_type(device);
|
||||
std::string chunk_size = "chunk_size";
|
||||
std::string chunk_start = "chunk_start";
|
||||
std::string chunk_end = "chunk_end";
|
||||
|
||||
stream << _size_t << " " << chunk_size << " = (" << bound << "+" << domain_size << "-1)/" << domain_size << ";" << std::endl;
|
||||
stream << _size_t << " " << chunk_start << " =" << domain_id << "*" << chunk_size << ";" << std::endl;
|
||||
stream << _size_t << " " << chunk_end << " = min(" << chunk_start << "+" << chunk_size << ", " << bound << ");" << std::endl;
|
||||
init = chunk_start;
|
||||
upper_bound = chunk_end;
|
||||
inc = "1";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Fun>
|
||||
inline void element_wise_loop_1D(kernel_generation_stream & stream, fetching_policy_type fetch, unsigned int simd_width,
|
||||
std::string const & i, std::string const & bound, std::string const & domain_id, std::string const & domain_size, driver::Device const & device, Fun const & generate_body)
|
||||
{
|
||||
std::string strwidth = tools::to_string(simd_width);
|
||||
std::string boundround = bound + "/" + strwidth;
|
||||
|
||||
std::string init, upper_bound, inc;
|
||||
fetching_loop_info(fetch, boundround, stream, init, upper_bound, inc, domain_id, domain_size, device);
|
||||
stream << "for(unsigned int " << i << " = " << init << "; " << i << " < " << upper_bound << "; " << i << " += " << inc << ")" << std::endl;
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
generate_body(simd_width);
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
|
||||
if (simd_width>1)
|
||||
{
|
||||
stream << "for(unsigned int " << i << " = " << boundround << "*" << strwidth << " + " << domain_id << "; " << i << " < " << bound << "; " << i << " += " + domain_size + ")" << std::endl;
|
||||
stream << "{" << std::endl;
|
||||
stream.inc_tab();
|
||||
generate_body(1);
|
||||
stream.dec_tab();
|
||||
stream << "}" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
#ifndef ISAAC_MODEL_TOOLS_HPP
|
||||
#define ISAAC_MODEL_TOOLS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
namespace tools
|
||||
{
|
||||
template<class T>
|
||||
std::vector<T> to_int_array(rapidjson::Value const & a)
|
||||
{
|
||||
size_t N = a.Size();
|
||||
std::vector<T> res(N);
|
||||
for(size_t i = 0 ; i < N ; ++i) res[i] = a[i].GetInt();
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::vector<T> to_float_array(rapidjson::Value const & a)
|
||||
{
|
||||
size_t N = a.Size();
|
||||
std::vector<T> res(N);
|
||||
for(size_t i = 0 ; i < N ; ++i) res[i] = a[i].GetDouble();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
144
lib/model/database.cpp
Normal file
144
lib/model/database.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#include <fstream>
|
||||
|
||||
#include "isaac/model/database.h"
|
||||
|
||||
#include "isaac/kernels/parse.h"
|
||||
#include "isaac/kernels/templates/axpy.h"
|
||||
#include "isaac/kernels/templates/dot.h"
|
||||
#include "isaac/kernels/templates/ger.h"
|
||||
#include "isaac/kernels/templates/gemv.h"
|
||||
#include "isaac/kernels/templates/gemm.h"
|
||||
|
||||
#include "json/rapidjson/document.h"
|
||||
#include "json/to_array.hpp"
|
||||
|
||||
#include "presets/broadwell.hpp"
|
||||
|
||||
#include "getenv.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static std::shared_ptr<templates::base> create(std::string const & template_name, std::vector<int> const & a)
|
||||
{
|
||||
templates::fetching_policy_type fetch[] = {templates::FETCH_FROM_LOCAL, templates::FETCH_FROM_GLOBAL_STRIDED, templates::FETCH_FROM_GLOBAL_CONTIGUOUS};
|
||||
if(template_name=="axpy")
|
||||
return std::shared_ptr<templates::base>(new templates::axpy(a[0], a[1], a[2], fetch[a[3]]));
|
||||
else if(template_name=="dot")
|
||||
return std::shared_ptr<templates::base>(new templates::dot(a[0], a[1], a[2], fetch[a[3]]));
|
||||
else if(template_name=="ger")
|
||||
return std::shared_ptr<templates::base>(new templates::ger(a[0], a[1], a[2], a[3], a[4], fetch[a[5]]));
|
||||
else if(template_name.find("gemv_n")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemv_n(a[0], a[1], a[2], a[3], a[4], fetch[a[5]]));
|
||||
else if(template_name.find("gemv_t")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemv_t(a[0], a[1], a[2], a[3], a[4], fetch[a[5]]));
|
||||
else if(template_name.find("gemm_nn")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_nn(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else if(template_name.find("gemm_tn")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_tn(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else if(template_name.find("gemm_nt")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_nt(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else if(template_name.find("gemm_tt")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_tt(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else
|
||||
throw std::invalid_argument("Invalid expression: " + template_name);
|
||||
}
|
||||
}
|
||||
|
||||
void database::import(std::string const & fname, driver::CommandQueue const & queue)
|
||||
{
|
||||
namespace js = rapidjson;
|
||||
map_type & result = cache_[queue];
|
||||
|
||||
//Parse the JSON document
|
||||
js::Document document;
|
||||
std::ifstream t(fname.c_str());
|
||||
if(!t) return;
|
||||
std::string str;
|
||||
t.seekg(0, std::ios::end);
|
||||
str.reserve(t.tellg());
|
||||
t.seekg(0, std::ios::beg);
|
||||
str.assign((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
|
||||
document.Parse<0>(str.c_str());
|
||||
//Deserialize
|
||||
std::vector<std::string> operations = {"axpy", "dot", "ger", "gemv_n", "gemv_t", "gemm_nn", "gemm_tn", "gemm_nt", "gemm_tt"};
|
||||
std::vector<std::string> dtype = {"float32", "float64"};
|
||||
for(auto & operation : operations)
|
||||
{
|
||||
const char * opcstr = operation.c_str();
|
||||
if(document.HasMember(opcstr))
|
||||
{
|
||||
expression_type etype = expression_type_from_string(operation);
|
||||
for(auto & elem : dtype)
|
||||
{
|
||||
const char * dtcstr = elem.c_str();
|
||||
if(document[opcstr].HasMember(dtcstr))
|
||||
{
|
||||
numeric_type dtype = numeric_type_from_string(elem);
|
||||
// Get profiles
|
||||
std::vector<std::shared_ptr<templates::base> > templates;
|
||||
js::Value const & profiles = document[opcstr][dtcstr]["profiles"];
|
||||
for (js::SizeType id = 0 ; id < profiles.Size() ; ++id)
|
||||
templates.push_back(detail::create(operation, json::to_int_array<int>(profiles[id])));
|
||||
if(templates.size()>1)
|
||||
{
|
||||
// Get predictor
|
||||
predictors::random_forest predictor(document[opcstr][dtcstr]["predictor"]);
|
||||
result[std::make_pair(etype, dtype)] = std::shared_ptr<model>(new model(etype, dtype, predictor, templates, queue));
|
||||
}
|
||||
else
|
||||
result[std::make_pair(etype, dtype)] = std::shared_ptr<model>(new model(etype, dtype, *templates[0], queue));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database::map_type& database::init(driver::CommandQueue const & queue)
|
||||
{
|
||||
map_type & result = cache_[queue];
|
||||
|
||||
numeric_type dtypes[] = {CHAR_TYPE, UCHAR_TYPE, SHORT_TYPE, USHORT_TYPE, INT_TYPE, UINT_TYPE, LONG_TYPE, ULONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE};
|
||||
expression_type etypes[] = {AXPY_TYPE, DOT_TYPE, GER_TYPE, GEMV_N_TYPE, GEMV_T_TYPE, GEMM_NN_TYPE, GEMM_NT_TYPE, GEMM_TN_TYPE, GEMM_TT_TYPE};
|
||||
|
||||
for(numeric_type dtype: dtypes)
|
||||
for(expression_type etype: etypes)
|
||||
result[std::make_pair(etype, dtype)] = std::shared_ptr<model>(new model(etype, dtype, *fallbacks[std::make_pair(etype, dtype)], queue));
|
||||
|
||||
std::string homepath = tools::getenv("HOME");
|
||||
if(homepath.size())
|
||||
import(homepath + "/.isaac/devices/device0.json", queue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
database::map_type& database::get(driver::CommandQueue const & queue)
|
||||
{
|
||||
std::map<driver::CommandQueue, map_type>::iterator it = cache_.find(queue);
|
||||
if(it == cache_.end())
|
||||
return init(queue);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void database::set(driver::CommandQueue const & queue, expression_type operation, numeric_type dtype, std::shared_ptr<model> const & model)
|
||||
{
|
||||
cache_[queue][std::make_pair(operation,dtype)] = model;
|
||||
}
|
||||
|
||||
std::map<driver::CommandQueue, database::map_type> database::cache_;
|
||||
|
||||
//Presets
|
||||
|
||||
#define DATABASE_ENTRY(VENDOR, ARCHITECTURE, STRING) \
|
||||
{std::make_tuple(driver::Device::Vendor::VENDOR, driver::Device::Architecture::ARCHITECTURE), STRING}
|
||||
|
||||
const std::map<std::tuple<driver::Device::Vendor, driver::Device::Architecture> , const char *> database::presets_ =
|
||||
{ DATABASE_ENTRY(INTEL, BROADWELL, presets::broadwell) };
|
||||
|
||||
|
||||
#undef DATABASE_ENTRY
|
||||
|
||||
|
||||
}
|
33
lib/model/json/to_array.hpp
Normal file
33
lib/model/json/to_array.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef ISAAC_MODEL_TOOLS_HPP
|
||||
#define ISAAC_MODEL_TOOLS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace json
|
||||
{
|
||||
|
||||
template<class T>
|
||||
std::vector<T> to_int_array(rapidjson::Value const & a)
|
||||
{
|
||||
size_t N = a.Size();
|
||||
std::vector<T> res(N);
|
||||
for(size_t i = 0 ; i < N ; ++i) res[i] = a[i].GetInt();
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::vector<T> to_float_array(rapidjson::Value const & a)
|
||||
{
|
||||
size_t N = a.Size();
|
||||
std::vector<T> res(N);
|
||||
for(size_t i = 0 ; i < N ; ++i) res[i] = a[i].GetDouble();
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -5,7 +5,6 @@
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
|
||||
#include "rapidjson/document.h"
|
||||
#include "isaac/kernels/parse.h"
|
||||
#include "isaac/kernels/templates/axpy.h"
|
||||
#include "isaac/kernels/templates/dot.h"
|
||||
@@ -16,13 +15,8 @@
|
||||
#include "isaac/exception/unknown_datatype.h"
|
||||
#include "isaac/exception/operation_not_supported.h"
|
||||
#include "isaac/model/model.h"
|
||||
#include "isaac/tools/make_vector.hpp"
|
||||
#include "isaac/tools/timer.hpp"
|
||||
#include "isaac/tools/getenv.hpp"
|
||||
|
||||
#include "database/broadwell.hpp"
|
||||
|
||||
#include "convert.hpp"
|
||||
#include "getenv.hpp"
|
||||
|
||||
|
||||
namespace isaac
|
||||
@@ -136,139 +130,6 @@ model::templates_container const & model::templates() const
|
||||
|
||||
///////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static expression_type get_expression_type(std::string const & name)
|
||||
{
|
||||
if(name=="axpy") return AXPY_TYPE;
|
||||
if(name=="dot") return DOT_TYPE;
|
||||
if(name=="ger") return GER_TYPE;
|
||||
if(name=="gemv_n") return GEMV_N_TYPE;
|
||||
if(name=="gemv_t") return GEMV_T_TYPE;
|
||||
if(name=="gemm_nn") return GEMM_NN_TYPE;
|
||||
if(name=="gemm_nt") return GEMM_NT_TYPE;
|
||||
if(name=="gemm_tn") return GEMM_TN_TYPE;
|
||||
if(name=="gemm_tt") return GEMM_TT_TYPE;
|
||||
throw std::invalid_argument("Invalid expression: " + name);
|
||||
}
|
||||
|
||||
static numeric_type get_dtype(std::string const & name)
|
||||
{
|
||||
if(name=="float32") return FLOAT_TYPE;
|
||||
if(name=="float64") return DOUBLE_TYPE;
|
||||
throw std::invalid_argument("Invalid datatype: " + name);
|
||||
}
|
||||
|
||||
static std::shared_ptr<templates::base> create(std::string const & template_name, std::vector<int> const & a)
|
||||
{
|
||||
templates::fetching_policy_type fetch[] = {templates::FETCH_FROM_LOCAL, templates::FETCH_FROM_GLOBAL_STRIDED, templates::FETCH_FROM_GLOBAL_CONTIGUOUS};
|
||||
if(template_name=="axpy")
|
||||
return std::shared_ptr<templates::base>(new templates::axpy(a[0], a[1], a[2], fetch[a[3]]));
|
||||
else if(template_name=="dot")
|
||||
return std::shared_ptr<templates::base>(new templates::dot(a[0], a[1], a[2], fetch[a[3]]));
|
||||
else if(template_name=="ger")
|
||||
return std::shared_ptr<templates::base>(new templates::ger(a[0], a[1], a[2], a[3], a[4], fetch[a[5]]));
|
||||
else if(template_name.find("gemv_n")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemv_n(a[0], a[1], a[2], a[3], a[4], fetch[a[5]]));
|
||||
else if(template_name.find("gemv_t")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemv_t(a[0], a[1], a[2], a[3], a[4], fetch[a[5]]));
|
||||
else if(template_name.find("gemm_nn")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_nn(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else if(template_name.find("gemm_tn")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_tn(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else if(template_name.find("gemm_nt")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_nt(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else if(template_name.find("gemm_tt")!=std::string::npos)
|
||||
return std::shared_ptr<templates::base>(new templates::gemm_tt(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], fetch[a[8]], fetch[a[9]], a[10], a[11]));
|
||||
else
|
||||
throw std::invalid_argument("Invalid expression: " + template_name);
|
||||
}
|
||||
}
|
||||
|
||||
void models::import(std::string const & fname, driver::CommandQueue const & queue)
|
||||
{
|
||||
namespace js = rapidjson;
|
||||
map_type & result = data_[queue];
|
||||
|
||||
//Parse the JSON document
|
||||
js::Document document;
|
||||
std::ifstream t(fname.c_str());
|
||||
if(!t) return;
|
||||
std::string str;
|
||||
t.seekg(0, std::ios::end);
|
||||
str.reserve(t.tellg());
|
||||
t.seekg(0, std::ios::beg);
|
||||
str.assign((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
|
||||
document.Parse<0>(str.c_str());
|
||||
//Deserialize
|
||||
std::vector<std::string> operations = {"axpy", "dot", "ger", "gemv_n", "gemv_t", "gemm_nn", "gemm_tn", "gemm_nt", "gemm_tt"};
|
||||
std::vector<std::string> dtype = {"float32", "float64"};
|
||||
for(auto & operation : operations)
|
||||
{
|
||||
const char * opcstr = operation.c_str();
|
||||
if(document.HasMember(opcstr))
|
||||
{
|
||||
expression_type etype = detail::get_expression_type(operation);
|
||||
for(auto & elem : dtype)
|
||||
{
|
||||
const char * dtcstr = elem.c_str();
|
||||
if(document[opcstr].HasMember(dtcstr))
|
||||
{
|
||||
numeric_type dtype = detail::get_dtype(elem);
|
||||
|
||||
// Get profiles
|
||||
std::vector<std::shared_ptr<templates::base> > templates;
|
||||
js::Value const & profiles = document[opcstr][dtcstr]["profiles"];
|
||||
for (js::SizeType id = 0 ; id < profiles.Size() ; ++id)
|
||||
templates.push_back(detail::create(operation, tools::to_int_array<int>(profiles[id])));
|
||||
|
||||
if(templates.size()>1)
|
||||
{
|
||||
// Get predictor
|
||||
predictors::random_forest predictor(document[opcstr][dtcstr]["predictor"]);
|
||||
result[std::make_pair(etype, dtype)] = std::shared_ptr<model>(new model(etype, dtype, predictor, templates, queue));
|
||||
}
|
||||
else
|
||||
result[std::make_pair(etype, dtype)] = std::shared_ptr<model>(new model(etype, dtype, *templates[0], queue));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
models::map_type& models::init(driver::CommandQueue const & queue)
|
||||
{
|
||||
map_type & result = data_[queue];
|
||||
|
||||
numeric_type dtypes[] = {CHAR_TYPE, UCHAR_TYPE, SHORT_TYPE, USHORT_TYPE, INT_TYPE, UINT_TYPE, LONG_TYPE, ULONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE};
|
||||
expression_type etypes[] = {AXPY_TYPE, DOT_TYPE, GER_TYPE, GEMV_N_TYPE, GEMV_T_TYPE, GEMM_NN_TYPE, GEMM_NT_TYPE, GEMM_TN_TYPE, GEMM_TT_TYPE};
|
||||
|
||||
for(numeric_type dtype: dtypes)
|
||||
for(expression_type etype: etypes)
|
||||
result[std::make_pair(etype, dtype)] = std::shared_ptr<model>(new model(etype, dtype, *fallbacks[std::make_pair(etype, dtype)], queue));
|
||||
|
||||
std::string homepath = tools::getenv("HOME");
|
||||
if(homepath.size())
|
||||
import(homepath + "/.isaac/devices/device0.json", queue);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
models::map_type& models::get(driver::CommandQueue const & queue)
|
||||
{
|
||||
std::map<driver::CommandQueue, map_type>::iterator it = data_.find(queue);
|
||||
if(it == data_.end())
|
||||
return init(queue);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void models::set(driver::CommandQueue const & queue, expression_type operation, numeric_type dtype, std::shared_ptr<model> const & model)
|
||||
{
|
||||
data_[queue][std::make_pair(operation,dtype)] = model;
|
||||
}
|
||||
|
||||
std::map<driver::CommandQueue, models::map_type> models::data_;
|
||||
|
||||
//
|
||||
|
||||
std::map<std::pair<expression_type, numeric_type>, std::shared_ptr<templates::base> > init_fallback()
|
||||
@@ -294,7 +155,4 @@ std::map<std::pair<expression_type, numeric_type>, std::shared_ptr<templates::ba
|
||||
|
||||
std::map<std::pair<expression_type, numeric_type>, std::shared_ptr<templates::base> > fallbacks = init_fallback();
|
||||
|
||||
const std::map<std::pair<driver::Device::VENDOR, driver::Device::ARCHITECTURE> , const char *>
|
||||
models::database_ = { { {driver::Device::VENDOR::INTEL, driver::Device::ARCHITECTURE::BROADWELL}, database::broadwell } };
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "isaac/model/predictors/random_forest.h"
|
||||
#include "../convert.hpp"
|
||||
#include "../json/to_array.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
||||
@@ -9,12 +10,12 @@ namespace predictors
|
||||
|
||||
random_forest::tree::tree(rapidjson::Value const & treerep)
|
||||
{
|
||||
children_left_ = tools::to_int_array<int>(treerep["children_left"]);
|
||||
children_right_ = tools::to_int_array<int>(treerep["children_right"]);
|
||||
threshold_ = tools::to_float_array<float>(treerep["threshold"]);
|
||||
feature_ = tools::to_float_array<float>(treerep["feature"]);
|
||||
children_left_ = json::to_int_array<int>(treerep["children_left"]);
|
||||
children_right_ = json::to_int_array<int>(treerep["children_right"]);
|
||||
threshold_ = json::to_float_array<float>(treerep["threshold"]);
|
||||
feature_ = json::to_float_array<float>(treerep["feature"]);
|
||||
for(rapidjson::SizeType i = 0 ; i < treerep["value"].Size() ; i++)
|
||||
value_.push_back(tools::to_float_array<float>(treerep["value"][i]));
|
||||
value_.push_back(json::to_float_array<float>(treerep["value"][i]));
|
||||
D_ = value_[0].size();
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
namespace database
|
||||
namespace presets
|
||||
{
|
||||
|
||||
static const char broadwell[] = {
|
@@ -4,7 +4,7 @@
|
||||
#include <stdexcept>
|
||||
#include "isaac/types.h"
|
||||
#include "isaac/array.h"
|
||||
#include "isaac/model/model.h"
|
||||
#include "isaac/model/database.h"
|
||||
#include "isaac/symbolic/expression.h"
|
||||
#include "isaac/symbolic/preset.h"
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace isaac
|
||||
}
|
||||
|
||||
/** @brief Executes a array_expression on the given models map*/
|
||||
void execute(controller<array_expression> const & c, models::map_type &models)
|
||||
void execute(controller<array_expression> const & c, database::map_type & models)
|
||||
{
|
||||
array_expression expression = c.x();
|
||||
driver::Context const & context = expression.context();
|
||||
|
@@ -2,7 +2,8 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "isaac/symbolic/io.h"
|
||||
#include "isaac/tools/to_string.hpp"
|
||||
|
||||
#include "to_string.hpp"
|
||||
|
||||
namespace isaac
|
||||
{
|
||||
|
@@ -29,7 +29,7 @@ extern "C"
|
||||
{
|
||||
std::list<is::driver::Event> levents;
|
||||
is::execution_options_type options(is::driver::CommandQueue(commandQueues[i],false), &levents, &waitlist);
|
||||
is::execute(is::control(operation, options), is::models::get(options.queue(context)));
|
||||
is::execute(is::control(operation, options), is::database::get(options.queue(context)));
|
||||
if(events)
|
||||
{
|
||||
events[i] = levents.front().handle().cl();
|
||||
|
@@ -115,7 +115,7 @@ def main():
|
||||
include =' src/include'.split() + ['external/boost/include', os.path.join(find_module("numpy")[1], "core", "include")]
|
||||
|
||||
#Source files
|
||||
src = 'src/lib/wrap/clBLAS.cpp src/lib/value_scalar.cpp src/lib/kernels/parse.cpp src/lib/kernels/templates/gemm.cpp src/lib/kernels/templates/gemv.cpp src/lib/kernels/templates/ger.cpp src/lib/kernels/templates/dot.cpp src/lib/kernels/templates/axpy.cpp src/lib/kernels/templates/base.cpp src/lib/kernels/stream.cpp src/lib/kernels/mapped_object.cpp src/lib/kernels/keywords.cpp src/lib/kernels/binder.cpp src/lib/array.cpp src/lib/symbolic/preset.cpp src/lib/symbolic/expression.cpp src/lib/symbolic/execute.cpp src/lib/symbolic/io.cpp src/lib/model/model.cpp src/lib/model/predictors/random_forest.cpp src/lib/exception/unknown_datatype.cpp src/lib/exception/operation_not_supported.cpp src/lib/driver/device.cpp src/lib/driver/program.cpp src/lib/driver/event.cpp src/lib/driver/context.cpp src/lib/driver/program_cache.cpp src/lib/driver/platform.cpp src/lib/driver/ndrange.cpp src/lib/driver/kernel.cpp src/lib/driver/handle.cpp src/lib/driver/command_queue.cpp src/lib/driver/check.cpp src/lib/driver/buffer.cpp src/lib/driver/backend.cpp '.split() + [os.path.join('src', 'wrap', sf) for sf in ['_isaac.cpp', 'core.cpp', 'driver.cpp', 'model.cpp', 'exceptions.cpp']]
|
||||
src = 'src/lib/array.cpp src/lib/wrap/clBLAS.cpp src/lib/value_scalar.cpp src/lib/kernels/mapped_object.cpp src/lib/kernels/parse.cpp src/lib/kernels/templates/base.cpp src/lib/kernels/templates/gemm.cpp src/lib/kernels/templates/gemv.cpp src/lib/kernels/templates/ger.cpp src/lib/kernels/templates/dot.cpp src/lib/kernels/templates/axpy.cpp src/lib/kernels/stream.cpp src/lib/kernels/keywords.cpp src/lib/kernels/binder.cpp src/lib/symbolic/preset.cpp src/lib/symbolic/expression.cpp src/lib/symbolic/execute.cpp src/lib/symbolic/io.cpp src/lib/model/model.cpp src/lib/model/database.cpp src/lib/model/predictors/random_forest.cpp src/lib/exception/unknown_datatype.cpp src/lib/exception/operation_not_supported.cpp src/lib/driver/program.cpp src/lib/driver/device.cpp src/lib/driver/event.cpp src/lib/driver/program_cache.cpp src/lib/driver/ndrange.cpp src/lib/driver/kernel.cpp src/lib/driver/handle.cpp src/lib/driver/command_queue.cpp src/lib/driver/check.cpp src/lib/driver/buffer.cpp src/lib/driver/backend.cpp src/lib/driver/context.cpp src/lib/driver/platform.cpp '.split() + [os.path.join('src', 'wrap', sf) for sf in ['_isaac.cpp', 'core.cpp', 'driver.cpp', 'model.cpp', 'exceptions.cpp']]
|
||||
boostsrc = 'external/boost/libs/'
|
||||
for s in ['numpy','python','smart_ptr','system','thread']:
|
||||
src = src + [x for x in recursive_glob('external/boost/libs/' + s + '/src/','.cpp') if 'win32' not in x and 'pthread' not in x]
|
||||
|
@@ -143,7 +143,7 @@ void export_driver()
|
||||
.add_property("name",&isc::driver::Platform::name)
|
||||
;
|
||||
|
||||
bp::enum_<isaac::driver::Device::VENDOR>
|
||||
bp::enum_<isaac::driver::Device::Vendor>
|
||||
("vendor")
|
||||
.value("AMD", isc::driver::Device::AMD)
|
||||
.value("INTEL", isc::driver::Device::INTEL)
|
||||
|
Reference in New Issue
Block a user