inline void memory_create(mem_handle & handle, std::size_t size_in_bytes, const void * host_ptr = NULL) { if (size_in_bytes > 0) { if (handle.get_active_handle_id() == MEMORY_NOT_INITIALIZED) handle.switch_active_handle_id(default_memory_type()); switch(handle.get_active_handle_id()) { case MAIN_MEMORY: handle.ram_handle() = cpu_ram::memory_create(size_in_bytes, host_ptr); handle.raw_size(size_in_bytes); break; #ifdef VIENNACL_WITH_OPENCL case OPENCL_MEMORY: handle.opencl_handle() = opencl::memory_create(size_in_bytes, host_ptr); handle.raw_size(size_in_bytes); break; #endif #ifdef VIENNACL_WITH_CUDA case CUDA_MEMORY: handle.cuda_handle() = cuda::memory_create(size_in_bytes, host_ptr); handle.raw_size(size_in_bytes); break; #endif default: throw "unknown memory handle!"; } } }
/** @brief Resize without initializing the new memory */ 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) { if (bytes_buffer_) delete[] bytes_buffer_; bytes_buffer_ = new char[buffer_size_]; } }
/** @brief Resize without initializing the new memory */ void raw_resize(mem_handle const & handle, std::size_t num) { buffer_size_ = sizeof(cpu_type) * num; #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) { if (bytes_buffer_) delete[] bytes_buffer_; bytes_buffer_ = new char[buffer_size_]; } }
explicit typesafe_host_array() : convert_to_opencl_( (default_memory_type() == OPENCL_MEMORY) ? true : false), bytes_buffer_(NULL), buffer_size_(0) {}
void typesafe_memory_copy(mem_handle const & handle_src, mem_handle & handle_dst) { if (handle_dst.get_active_handle_id() == MEMORY_NOT_INITIALIZED) handle_dst.switch_active_handle_id(default_memory_type()); std::size_t element_size_src = detail::element_size<DataType>(handle_src.get_active_handle_id()); std::size_t element_size_dst = detail::element_size<DataType>(handle_dst.get_active_handle_id()); if (element_size_src != element_size_dst) { // Data needs to be converted. typesafe_host_array<DataType> buffer_src(handle_src); typesafe_host_array<DataType> buffer_dst(handle_dst, handle_src.raw_size() / element_size_src); // // Step 1: Fill buffer_dst depending on where the data resides: // DataType const * src_data; switch (handle_src.get_active_handle_id()) { case MAIN_MEMORY: src_data = reinterpret_cast<DataType const *>(handle_src.ram_handle().get()); for (std::size_t i=0; i<buffer_dst.size(); ++i) buffer_dst.set(i, src_data[i]); break; #ifdef VIENNACL_WITH_OPENCL case OPENCL_MEMORY: buffer_src.resize(handle_src, handle_src.raw_size() / element_size_src); opencl::memory_read(handle_src.opencl_handle(), 0, buffer_src.raw_size(), buffer_src.get()); for (std::size_t i=0; i<buffer_dst.size(); ++i) buffer_dst.set(i, buffer_src[i]); break; #endif #ifdef VIENNACL_WITH_CUDA case CUDA_MEMORY: buffer_src.resize(handle_src, handle_src.raw_size() / element_size_src); cuda::memory_read(handle_src.cuda_handle(), 0, buffer_src.raw_size(), buffer_src.get()); for (std::size_t i=0; i<buffer_dst.size(); ++i) buffer_dst.set(i, buffer_src[i]); break; #endif default: throw "unsupported memory domain"; } // // Step 2: Write to destination // if (handle_dst.raw_size() == buffer_dst.raw_size()) viennacl::backend::memory_write(handle_dst, 0, buffer_dst.raw_size(), buffer_dst.get()); else viennacl::backend::memory_create(handle_dst, buffer_dst.raw_size(), buffer_dst.get()); } else { // No data conversion required. typesafe_host_array<DataType> buffer(handle_src); switch (handle_src.get_active_handle_id()) { case MAIN_MEMORY: switch (handle_dst.get_active_handle_id()) { case MAIN_MEMORY: case OPENCL_MEMORY: case CUDA_MEMORY: if (handle_dst.raw_size() == handle_src.raw_size()) viennacl::backend::memory_write(handle_dst, 0, handle_src.raw_size(), handle_src.ram_handle().get()); else viennacl::backend::memory_create(handle_dst, handle_src.raw_size(), handle_src.ram_handle().get()); break; default: throw "unsupported destination memory domain"; } break; case OPENCL_MEMORY: switch (handle_dst.get_active_handle_id()) { case MAIN_MEMORY: if (handle_dst.raw_size() != handle_src.raw_size()) viennacl::backend::memory_create(handle_dst, handle_src.raw_size()); viennacl::backend::memory_read(handle_src, 0, handle_src.raw_size(), handle_dst.ram_handle().get()); break; case OPENCL_MEMORY: if (handle_dst.raw_size() != handle_src.raw_size()) viennacl::backend::memory_create(handle_dst, handle_src.raw_size()); viennacl::backend::memory_copy(handle_src, handle_dst, 0, 0, handle_src.raw_size()); break; case CUDA_MEMORY: if (handle_dst.raw_size() != handle_src.raw_size()) viennacl::backend::memory_create(handle_dst, handle_src.raw_size()); buffer.resize(handle_src, handle_src.raw_size() / element_size_src); viennacl::backend::memory_read(handle_src, 0, handle_src.raw_size(), buffer.get()); viennacl::backend::memory_write(handle_dst, 0, handle_src.raw_size(), buffer.get()); break; default: throw "unsupported destination memory domain"; } break; case CUDA_MEMORY: switch (handle_dst.get_active_handle_id()) { case MAIN_MEMORY: if (handle_dst.raw_size() != handle_src.raw_size()) viennacl::backend::memory_create(handle_dst, handle_src.raw_size()); viennacl::backend::memory_read(handle_src, 0, handle_src.raw_size(), handle_dst.ram_handle().get()); break; case OPENCL_MEMORY: if (handle_dst.raw_size() != handle_src.raw_size()) viennacl::backend::memory_create(handle_dst, handle_src.raw_size()); buffer.resize(handle_src, handle_src.raw_size() / element_size_src); viennacl::backend::memory_read(handle_src, 0, handle_src.raw_size(), buffer.get()); viennacl::backend::memory_write(handle_dst, 0, handle_src.raw_size(), buffer.get()); break; case CUDA_MEMORY: if (handle_dst.raw_size() != handle_src.raw_size()) viennacl::backend::memory_create(handle_dst, handle_src.raw_size()); viennacl::backend::memory_copy(handle_src, handle_dst, 0, 0, handle_src.raw_size()); break; default: throw "unsupported destination memory domain"; } break; default: throw "unsupported source memory domain"; } } }