Files
triton/lib/jit/generation/engine/stream.cpp
2017-01-17 20:33:46 -05:00

112 lines
3.8 KiB
C++

/* Copyright 2015-2017 Philippe Tillet
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "isaac/jit/generation/engine/stream.h"
#include "isaac/tools/cpp/string.hpp"
namespace isaac
{
kernel_generation_stream::kgenstream::kgenstream(std::ostringstream& oss,unsigned int const & tab_count) :
oss_(oss), tab_count_(tab_count)
{ }
int kernel_generation_stream::kgenstream::sync()
{
for (unsigned int i=0; i<tab_count_;++i)
oss_ << " ";
std::string next = str();
oss_ << next;
str("");
return !oss_;
}
kernel_generation_stream::kgenstream:: ~kgenstream()
{ pubsync(); }
void kernel_generation_stream::process(std::string& str)
{
#define ADD_KEYWORD(NAME, OPENCL_NAME, CUDA_NAME) tools::find_and_replace(str, "$" + std::string(NAME), (backend_==driver::CUDA)?CUDA_NAME:OPENCL_NAME);
ADD_KEYWORD("GLOBAL_IDX_0", "get_global_id(0)", "(blockIdx.x*blockDim.x + threadIdx.x)")
ADD_KEYWORD("GLOBAL_IDX_1", "get_global_id(1)", "(blockIdx.y*blockDim.y + threadIdx.y)")
ADD_KEYWORD("GLOBAL_IDX_2", "get_global_id(2)", "(blockIdx.z*blockDim.z + threadIdx.z)")
ADD_KEYWORD("GLOBAL_SIZE_0", "get_global_size(0)", "(blockDim.x*gridDim.x)")
ADD_KEYWORD("GLOBAL_SIZE_1", "get_global_size(1)", "(blockDim.y*gridDim.y)")
ADD_KEYWORD("GLOBAL_SIZE_2", "get_global_size(2)", "(blockDim.z*gridDim.z)")
ADD_KEYWORD("LOCAL_IDX_0", "get_local_id(0)", "threadIdx.x")
ADD_KEYWORD("LOCAL_IDX_1", "get_local_id(1)", "threadIdx.y")
ADD_KEYWORD("LOCAL_IDX_2", "get_local_id(2)", "threadIdx.z")
ADD_KEYWORD("LOCAL_SIZE_0", "get_local_size(0)", "blockDim.x")
ADD_KEYWORD("LOCAL_SIZE_1", "get_local_size(1)", "blockDim.y")
ADD_KEYWORD("LOCAL_SIZE_2", "get_local_size(2)", "blockDim.z")
ADD_KEYWORD("GROUP_IDX_0", "get_group_id(0)", "blockIdx.x")
ADD_KEYWORD("GROUP_IDX_1", "get_group_id(1)", "blockIdx.y")
ADD_KEYWORD("GROUP_IDX_2", "get_group_id(2)", "blockIdx.z")
ADD_KEYWORD("GROUP_SIZE_0", "get_ng(0)", "GridDim.x")
ADD_KEYWORD("GROUP_SIZE_1", "get_ng(1)", "GridDim.y")
ADD_KEYWORD("GROUP_SIZE_2", "get_ng(2)", "GridDim.z")
ADD_KEYWORD("LOCAL_BARRIER", "barrier(CLK_LOCAL_MEM_FENCE)", "__syncthreads()")
ADD_KEYWORD("LOCAL_PTR", "__local", "")
ADD_KEYWORD("LOCAL", "__local", "__shared__")
ADD_KEYWORD("GLOBAL", "__global", "")
ADD_KEYWORD("SIZE_T", "int", "int")
ADD_KEYWORD("KERNEL", "__kernel", "extern \"C\" __global__")
ADD_KEYWORD("MAD", "mad", "fma")
#undef ADD_KEYWORD
}
kernel_generation_stream::kernel_generation_stream(driver::backend_type backend) : std::ostream(new kgenstream(oss,tab_count_)), tab_count_(0), backend_(backend)
{ }
kernel_generation_stream::~kernel_generation_stream()
{ delete rdbuf(); }
std::string kernel_generation_stream::str()
{
std::string next = oss.str();
process(next);
return next;
}
void kernel_generation_stream::inc_tab()
{ ++tab_count_; }
void kernel_generation_stream::dec_tab()
{ --tab_count_; }
}