All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.hpp
Go to the documentation of this file.
#ifndef VIENNACL_BACKEND_UTIL_HPP
#define VIENNACL_BACKEND_UTIL_HPP
/* =========================================================================
Copyright (c) 2010-2016, 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 manual)
License: MIT (X11), see file LICENSE in the base directory
============================================================================= */
#include <vector>
#include <cassert>
#include "viennacl/forwards.h"
#include "viennacl/backend/mem_handle.hpp"
#ifdef VIENNACL_WITH_OPENCL
#include "viennacl/backend/opencl.hpp"
#endif
namespace viennacl
{
namespace backend
{
namespace detail
{
template<typename T>
struct convert_to_opencl
{
typedef T type;
enum { special = 0 };
};
#ifdef VIENNACL_WITH_OPENCL
template<>
struct convert_to_opencl<unsigned int>
{
typedef cl_uint type;
//enum { special = (sizeof(unsigned int) != sizeof(cl_uint)) };
enum { special = 1 };
};
template<>
struct convert_to_opencl<int>
{
typedef cl_int type;
//enum { special = (sizeof(int) != sizeof(cl_int)) };
enum { special = 1 };
};
template<>
struct convert_to_opencl<unsigned long>
{
typedef cl_ulong type;
//enum { special = (sizeof(unsigned long) != sizeof(cl_ulong)) };
enum { special = 1 };
};
template<>
struct convert_to_opencl<long>
{
typedef cl_long type;
//enum { special = (sizeof(long) != sizeof(cl_long)) };
enum { special = 1 };
};
#endif
} //namespace detail
template<typename T, bool special = detail::convert_to_opencl<T>::special>
class typesafe_host_array
{
typedef T cpu_type;
typedef typename detail::convert_to_opencl<T>::type target_type;
public:
explicit typesafe_host_array() : bytes_buffer_(NULL), buffer_size_(0) {}
explicit typesafe_host_array(mem_handle const & handle, vcl_size_t num = 0) : bytes_buffer_(NULL), buffer_size_(sizeof(cpu_type) * num)
{
resize(handle, num);
}
~typesafe_host_array() { delete[] bytes_buffer_; }
//
// Setter and Getter
//
void * get() { return reinterpret_cast<void *>(bytes_buffer_); }
vcl_size_t raw_size() const { return buffer_size_; }
vcl_size_t element_size() const { return sizeof(cpu_type); }
vcl_size_t size() const { return buffer_size_ / element_size(); }
template<typename U>
void set(vcl_size_t index, U value)
{
reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value);
}
//
// Resize functionality
//
void raw_resize(mem_handle const & /*handle*/, vcl_size_t num)
{
buffer_size_ = sizeof(cpu_type) * num;
if (num > 0)
{
delete[] bytes_buffer_;
bytes_buffer_ = new char[buffer_size_];
}
}
void resize(mem_handle const & handle, vcl_size_t num)
{
raw_resize(handle, num);
if (num > 0)
{
for (vcl_size_t i=0; i<buffer_size_; ++i)
bytes_buffer_[i] = 0;
}
}
cpu_type operator[](vcl_size_t index) const
{
assert(index < size() && bool("index out of bounds"));
return reinterpret_cast<cpu_type *>(bytes_buffer_)[index];
}
private:
char * bytes_buffer_;
vcl_size_t buffer_size_;
};
template<typename T>
class typesafe_host_array<T, true>
{
typedef T cpu_type;
typedef typename detail::convert_to_opencl<T>::type target_type;
public:
explicit typesafe_host_array() : convert_to_opencl_( (default_memory_type() == OPENCL_MEMORY) ? true : false), bytes_buffer_(NULL), buffer_size_(0) {}
explicit typesafe_host_array(mem_handle const & handle, vcl_size_t num = 0) : convert_to_opencl_(false), bytes_buffer_(NULL), buffer_size_(sizeof(cpu_type) * num)
{
resize(handle, num);
}
~typesafe_host_array() { delete[] bytes_buffer_; }
//
// Setter and Getter
//
template<typename U>
void set(vcl_size_t index, U value)
{
#ifdef VIENNACL_WITH_OPENCL
if (convert_to_opencl_)
reinterpret_cast<target_type *>(bytes_buffer_)[index] = static_cast<target_type>(value);
else
#endif
reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value);
}
void * get() { return reinterpret_cast<void *>(bytes_buffer_); }
cpu_type operator[](vcl_size_t index) const
{
assert(index < size() && bool("index out of bounds"));
#ifdef VIENNACL_WITH_OPENCL
if (convert_to_opencl_)
return static_cast<cpu_type>(reinterpret_cast<target_type *>(bytes_buffer_)[index]);
#endif
return reinterpret_cast<cpu_type *>(bytes_buffer_)[index];
}
vcl_size_t raw_size() const { return buffer_size_; }
vcl_size_t element_size() const
{
#ifdef VIENNACL_WITH_OPENCL
if (convert_to_opencl_)
return sizeof(target_type);
#endif
return sizeof(cpu_type);
}
vcl_size_t size() const { return buffer_size_ / element_size(); }
//
// Resize functionality
//
void raw_resize(mem_handle const & handle, vcl_size_t num)
{
buffer_size_ = sizeof(cpu_type) * num;
(void)handle; //silence unused variable warning if compiled without OpenCL support
#ifdef VIENNACL_WITH_OPENCL
memory_types mem_type = handle.get_active_handle_id();
if (mem_type == MEMORY_NOT_INITIALIZED)
mem_type = default_memory_type();
if (mem_type == OPENCL_MEMORY)
{
convert_to_opencl_ = true;
buffer_size_ = sizeof(target_type) * num;
}
#endif
if (num > 0)
{
delete[] bytes_buffer_;
bytes_buffer_ = new char[buffer_size_];
}
}
void resize(mem_handle const & handle, vcl_size_t num)
{
raw_resize(handle, num);
if (num > 0)
{
for (vcl_size_t i=0; i<buffer_size_; ++i)
bytes_buffer_[i] = 0;
}
}
private:
bool convert_to_opencl_;
char * bytes_buffer_;
vcl_size_t buffer_size_;
};
} //backend
} //viennacl
#endif
viennacl::backend::typesafe_host_array
Helper class implementing an array on the host. Default case: No conversion necessary.
Definition: util.hpp:92
viennacl::backend::typesafe_host_array::raw_resize
void raw_resize(mem_handle const &, vcl_size_t num)
Resize without initializing the new memory.
Definition: util.hpp:125
viennacl::backend::typesafe_host_array::element_size
vcl_size_t element_size() const
Definition: util.hpp:112
viennacl::backend::typesafe_host_array< T, true >::operator[]
cpu_type operator[](vcl_size_t index) const
Definition: util.hpp:197
viennacl::backend::typesafe_host_array< T, true >::typesafe_host_array
typesafe_host_array(mem_handle const &handle, vcl_size_t num=0)
Definition: util.hpp:174
viennacl::backend::typesafe_host_array::size
vcl_size_t size() const
Definition: util.hpp:113
viennacl::backend::typesafe_host_array::operator[]
cpu_type operator[](vcl_size_t index) const
Definition: util.hpp:149
viennacl::OPENCL_MEMORY
Definition: forwards.h:349
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
viennacl::backend::typesafe_host_array::resize
void resize(mem_handle const &handle, vcl_size_t num)
Resize including initialization of new memory (cf. std::vector<>)
Definition: util.hpp:138
viennacl::backend::typesafe_host_array::typesafe_host_array
typesafe_host_array(mem_handle const &handle, vcl_size_t num=0)
Definition: util.hpp:100
viennacl::backend::detail::convert_to_opencl::special
Definition: util.hpp:48
viennacl::backend::typesafe_host_array< T, true >::element_size
vcl_size_t element_size() const
Definition: util.hpp:208
viennacl::MEMORY_NOT_INITIALIZED
Definition: forwards.h:347
viennacl::backend::typesafe_host_array< T, true >::raw_resize
void raw_resize(mem_handle const &handle, vcl_size_t num)
Resize without initializing the new memory.
Definition: util.hpp:223
mem_handle.hpp
Implements the multi-memory-domain handle.
viennacl::backend::detail::convert_to_opencl::type
T type
Definition: util.hpp:47
viennacl::backend::typesafe_host_array< T, true >::~typesafe_host_array
~typesafe_host_array()
Definition: util.hpp:179
viennacl::backend::typesafe_host_array< T, true >::set
void set(vcl_size_t index, U value)
Definition: util.hpp:186
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::backend::typesafe_host_array< T, true >::typesafe_host_array
typesafe_host_array()
Definition: util.hpp:172
viennacl::backend::default_memory_type
memory_types default_memory_type()
Returns the default memory type for the given configuration.
Definition: mem_handle.hpp:73
viennacl::backend::typesafe_host_array::typesafe_host_array
typesafe_host_array()
Definition: util.hpp:98
viennacl::backend::typesafe_host_array< T, true >::size
vcl_size_t size() const
Definition: util.hpp:216
viennacl::backend::typesafe_host_array< T, true >::resize
void resize(mem_handle const &handle, vcl_size_t num)
Resize including initialization of new memory (cf. std::vector<>)
Definition: util.hpp:249
viennacl::backend::typesafe_host_array::set
void set(vcl_size_t index, U value)
Definition: util.hpp:115
viennacl::backend::mem_handle
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:89
viennacl::backend::typesafe_host_array::~typesafe_host_array
~typesafe_host_array()
Definition: util.hpp:105
opencl.hpp
Implementations for the OpenCL backend functionality.
viennacl::traits::handle
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
viennacl::memory_types
memory_types
Definition: forwards.h:345
viennacl::backend::typesafe_host_array::raw_size
vcl_size_t raw_size() const
Definition: util.hpp:111
viennacl::backend::typesafe_host_array< T, true >::raw_size
vcl_size_t raw_size() const
Definition: util.hpp:207
viennacl::backend::detail::convert_to_opencl
Helper struct for converting a type to its OpenCL pendant.
Definition: util.hpp:45
viennacl::backend::mem_handle::get_active_handle_id
memory_types get_active_handle_id() const
Returns an ID for the currently active memory buffer. Other memory buffers might contain old or no da...
Definition: mem_handle.hpp:118