summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJin Wang <[email protected]>2014-10-18 23:07:53 -0400
committerJin Wang <[email protected]>2016-07-05 09:05:36 -0400
commit582106ec595bb7745db092f2f4aa2b0fb9521b16 (patch)
tree8622510691992e4bb4802f60a80a3e9ba8c07127
parent70e02ee5283cb96f0edcb46a15edf0ab6e1d0697 (diff)
MOD: add child kernel stream and scheduling support
-rw-r--r--src/abstract_hardware_model.cc77
-rw-r--r--src/abstract_hardware_model.h39
-rw-r--r--src/cuda-sim/cuda-sim.cc9
-rw-r--r--src/cuda-sim/cuda_device_runtime.cc31
-rw-r--r--src/cuda-sim/ptx_sim.h3
-rw-r--r--src/gpgpu-sim/gpu-sim.cc4
-rw-r--r--src/gpgpu-sim/gpu-sim.h20
-rw-r--r--src/gpgpusim_entrypoint.cc9
-rw-r--r--src/stream_manager.cc39
9 files changed, 199 insertions, 32 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 84d165c..b19b9d1 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -565,6 +565,10 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *
m_num_cores_running=0;
m_uid = m_next_uid++;
m_param_mem = new memory_space_impl<8192>("param",64*1024);
+
+ //Jin: parent and child kernel management for CDP
+ m_parent_kernel = NULL;
+
}
kernel_info_t::~kernel_info_t()
@@ -578,6 +582,79 @@ std::string kernel_info_t::name() const
return m_kernel_entry->get_name();
}
+//Jin: parent and child kernel management for CDP
+void kernel_info_t::set_parent(kernel_info_t * parent,
+ dim3 parent_ctaid, dim3 parent_tid) {
+ m_parent_kernel = parent;
+ m_parent_ctaid = parent_ctaid;
+ m_parent_tid = parent_tid;
+ parent->set_child(this);
+}
+
+void kernel_info_t::set_child(kernel_info_t * child) {
+ m_child_kernels.push_back(child);
+}
+
+bool kernel_info_t::is_finished() {
+ if(done() && children_all_finished())
+ return true;
+ else
+ return false;
+}
+
+bool kernel_info_t::children_all_finished() {
+ for(auto child = m_child_kernels.begin(); child != m_child_kernels.end(); child++)
+ {
+ if(!(*child)->is_finished())
+ return false;
+ }
+ return true;
+}
+
+void kernel_info_t::notify_parent_finished() {
+ if(m_parent_kernel) {
+ g_stream_manager->register_finished_kernel(m_parent_kernel->get_uid());
+ }
+}
+
+CUstream_st * kernel_info_t::create_stream_cta(dim3 ctaid) {
+ assert(get_default_stream_cta(ctaid));
+ CUstream_st * stream = new CUstream_st();
+ g_stream_manager->add_stream(stream);
+ assert(m_cta_streams.find(ctaid) != m_cta_streams.end());
+ assert(m_cta_streams[ctaid].size() >= 1); //must have default stream
+ m_cta_streams[ctaid].push_back(stream);
+
+ return stream;
+}
+
+CUstream_st * kernel_info_t::get_default_stream_cta(dim3 ctaid) {
+ if(m_cta_streams.find(ctaid) != m_cta_streams.end()) {
+ assert(m_cta_streams[ctaid].size() >= 1); //already created, must have default stream
+ return *(m_cta_streams[ctaid].begin());
+ }
+ else {
+ m_cta_streams[ctaid] = std::list<CUstream_st *>();
+ CUstream_st * stream = new CUstream_st();
+ g_stream_manager->add_stream(stream);
+ m_cta_streams[ctaid].push_back(stream);
+ return stream;
+ }
+}
+
+bool kernel_info_t::cta_has_stream(dim3 ctaid, CUstream_st* stream) {
+ if(m_cta_streams.find(ctaid) == m_cta_streams.end())
+ return false;
+
+ std::list<CUstream_st *> &stream_list = m_cta_streams[ctaid];
+ if(std::find(stream_list.begin(), stream_list.end(), stream)
+ == stream_list.end())
+ return false;
+ else
+ return true;
+}
+
+
simt_stack::simt_stack( unsigned wid, unsigned warpSize)
{
m_warp_id=wid;
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index ba4ea29..16f4b31 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -154,15 +154,35 @@ enum _memory_op_t {
#include <stdlib.h>
#include <map>
#include <deque>
+#include <algorithm>
#if !defined(__VECTOR_TYPES_H__)
struct dim3 {
unsigned int x, y, z;
};
#endif
+struct dim3comp {
+ bool operator() (const dim3 & a, const dim3 & b) const
+ {
+ if(a.z < b.z)
+ return true;
+ else if(a.y < b.y)
+ return true;
+ else if (a.x < b.x)
+ return true;
+ else
+ return false;
+ }
+};
void increment_x_then_y_then_z( dim3 &i, const dim3 &bound);
+//Jin: child kernel information for CDP
+#include "stream_manager.h"
+class stream_manager;
+struct CUstream_st;
+extern stream_manager * g_stream_manager;
+
class kernel_info_t {
public:
// kernel_info_t()
@@ -250,6 +270,25 @@ private:
std::list<class ptx_thread_info *> m_active_threads;
class memory_space *m_param_mem;
+
+public:
+ //Jin: parent and child kernel management for CDP
+ void set_parent(kernel_info_t * parent, dim3 parent_ctaid, dim3 parent_tid);
+ void set_child(kernel_info_t * child);
+ bool is_finished();
+ bool children_all_finished();
+ void notify_parent_finished();
+ CUstream_st * create_stream_cta(dim3 ctaid);
+ CUstream_st * get_default_stream_cta(dim3 ctaid);
+ bool cta_has_stream(dim3 ctaid, CUstream_st* stream);
+
+private:
+ kernel_info_t * m_parent_kernel;
+ dim3 m_parent_ctaid;
+ dim3 m_parent_tid;
+ std::list<kernel_info_t *> m_child_kernels; //child kernel launched
+ std::map< dim3, std::list<CUstream_st *>, dim3comp > m_cta_streams; //streams created in each CTA
+
};
struct core_config {
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 4933029..482e3f6 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -1762,8 +1762,13 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL )
extern stream_manager *g_stream_manager;
//openCL kernel simulation calls don't register the kernel so we don't register its exit
- if(!openCL)
- g_stream_manager->register_finished_kernel(kernel.get_uid());
+ if(!openCL) {
+
+ //Jin: for CDP, children should be finished first
+ if(kernel.is_finished()) {
+ g_stream_manager->register_finished_kernel(kernel.get_uid());
+ }
+ }
//******PRINTING*******
printf( "GPGPU-Sim: Done functional simulation (%u instructions simulated).\n", g_ptx_sim_num_insn );
diff --git a/src/cuda-sim/cuda_device_runtime.cc b/src/cuda-sim/cuda_device_runtime.cc
index 937eec8..4d8d1e1 100644
--- a/src/cuda-sim/cuda_device_runtime.cc
+++ b/src/cuda-sim/cuda_device_runtime.cc
@@ -21,8 +21,7 @@
}
std::map<void *, kernel_info_t *> g_cuda_device_launch_map;
-struct CUstream_st * g_device_default_stream = NULL;
-extern stream_manager *g_stream_manager;
+extern stream_manager * g_stream_manager;
//Handling device runtime api:
//void * cudaGetParameterBufferV2(void *func, dim3 gridDimension, dim3 blockDimension, unsigned int sharedMemSize)
@@ -78,7 +77,13 @@ void gpgpusim_cuda_getParameterBufferV2(const ptx_instruction * pI, ptx_thread_i
DEV_RUNTIME_REPORT("child kernel arg size total " << child_kernel_arg_size << ", parameter buffer allocated at " << param_buffer);
//create child kernel_info_t and index it with parameter_buffer address
- kernel_info_t * child_grid = new kernel_info_t(gridDim, blockDim, child_kernel_entry);
+ kernel_info_t * child_grid = new kernel_info_t(gridDim, blockDim, child_kernel_entry);
+ kernel_info_t & parent_grid = thread->get_kernel();
+ DEV_RUNTIME_REPORT("child kernel launched by " << parent_grid.name() << ", cta (" <<
+ thread->get_ctaid().x << ", " << thread->get_ctaid().y << ", " << thread->get_ctaid().z <<
+ "), thread (" << thread->get_tid().x << ", " << thread->get_tid().y << ", " << thread->get_tid().z <<
+ ")");
+ child_grid->set_parent(&parent_grid, thread->get_ctaid(), thread->get_tid());
assert(g_cuda_device_launch_map.find(param_buffer) == g_cuda_device_launch_map.end());
g_cuda_device_launch_map[param_buffer] = child_grid;
@@ -137,28 +142,30 @@ void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info *
for(unsigned n = 0; n < child_kernel_arg_size; n++) {
unsigned char one_byte;
thread->get_gpu()->get_global_memory()->read((size_t)parameter_buffer + n, 1, &one_byte);
+ std::cout << "one byte " << std::hex << one_byte << "\n";
child_kernel_param_mem->write(param_start_address + n, 1, &one_byte, NULL, NULL);
}
}
else if(arg == 1) { //cudaStream for the child kernel
assert(size == sizeof(cudaStream_t));
thread->m_local_mem->read(from_addr, size, &child_stream);
- if(child_stream == 0) { //default stream on device
- if(!g_device_default_stream) {
- //g_device_default_stream = new struct CUstream_st();
- //g_stream_manager->add_stream(g_device_default_stream);
- }
- child_stream = g_device_default_stream;
+
+ kernel_info_t & parent_kernel = thread->get_kernel();
+ if(child_stream == 0) { //default stream on device for current CTA
+ child_stream = parent_kernel.get_default_stream_cta(thread->get_ctaid());
+ }
+ else {
+ assert(parent_kernel.cta_has_stream(thread->get_ctaid(), child_stream));
}
-// DEV_RUNTIME_REPORT("launching child kernel to stream " << child_stream->get_uid());
+ DEV_RUNTIME_REPORT("launching child kernel to stream " << child_stream->get_uid() << " " << child_stream);
}
}
//launch child kernel
stream_operation op(child_grid, g_ptx_sim_mode, child_stream);
-// g_stream_manager->push(op);
-// g_cuda_device_launch_map.erase(parameter_buffer);
+ g_stream_manager->push(op);
+ g_cuda_device_launch_map.erase(parameter_buffer);
//set retval0
const operand_info &actual_return_op = pI->operand_lookup(0); //retval0
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index f926e6d..ea171c5 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -418,6 +418,9 @@ public:
void or_reduction(unsigned ctaid, unsigned barid, bool value) {m_core->or_reduction(ctaid,barid,value);}
void popc_reduction(unsigned ctaid, unsigned barid, bool value) {m_core->popc_reduction(ctaid,barid,value);}
+ //Jin: get corresponding kernel grid for CDP purpose
+ kernel_info_t & get_kernel() { return m_kernel; }
+
public:
addr_t m_last_effective_address;
bool m_branch_taken;
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index eafb909..47dbc89 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -622,6 +622,10 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config )
*active_sms=0;
last_liveness_message_time = 0;
+
+ //Jin: functional simulation for CDP
+ m_functional_sim = false;
+ m_functional_sim_kernel = NULL;
}
int gpgpu_sim::shared_mem_size() const
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index 33fffd3..a2d1b9b 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -492,6 +492,7 @@ private:
std::string executed_kernel_info_string(); //< format the kernel information into a string for stat printout
void clear_executed_kernel_info(); //< clear the kernel information after stat printout
+
public:
unsigned long long gpu_sim_insn;
unsigned long long gpu_tot_sim_insn;
@@ -504,6 +505,25 @@ public:
void change_cache_config(FuncCache cache_config);
void set_cache_config(std::string kernel_name);
+ //Jin: functional simulation for CDP
+private:
+ //set by stream operation every time a functoinal simulation is done
+ bool m_functional_sim;
+ kernel_info_t * m_functional_sim_kernel;
+
+public:
+ bool is_functional_sim() { return m_functional_sim; }
+ kernel_info_t * get_functional_kernel() { return m_functional_sim_kernel; }
+ void functional_launch(kernel_info_t * k) {
+ m_functional_sim = true;
+ m_functional_sim_kernel = k;
+ }
+ void finish_functional_sim(kernel_info_t * k) {
+ assert(m_functional_sim);
+ assert(m_functional_sim_kernel == k);
+ m_functional_sim = false;
+ m_functional_sim_kernel = NULL;
+ }
};
#endif
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index 6ba38eb..31f3a41 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -127,6 +127,15 @@ void *gpgpu_sim_thread_concurrent(void*)
if(g_stream_manager->operation(&sim_cycles) && !g_the_gpu->active())
break;
+ //functional simulation
+ if( g_the_gpu->is_functional_sim()) {
+ kernel_info_t * kernel = g_the_gpu->get_functional_kernel();
+ assert(kernel);
+ gpgpu_cuda_ptx_sim_main_func(*kernel);
+ g_the_gpu->finish_functional_sim(kernel);
+ }
+
+ //performance simulation
if( g_the_gpu->active() ) {
g_the_gpu->cycle();
sim_cycles = true;
diff --git a/src/stream_manager.cc b/src/stream_manager.cc
index dd42f0a..1f93c03 100644
--- a/src/stream_manager.cc
+++ b/src/stream_manager.cc
@@ -155,7 +155,7 @@ void stream_operation::do_operation( gpgpu_sim *gpu )
gpu->set_cache_config(m_kernel->name());
printf("kernel \'%s\' transfer to GPU hardware scheduler\n", m_kernel->name().c_str() );
if( m_sim_mode )
- gpgpu_cuda_ptx_sim_main_func( *m_kernel );
+ gpu->functional_launch( m_kernel );
else
gpu->launch( m_kernel );
}
@@ -212,11 +212,9 @@ bool stream_manager::operation( bool * sim)
bool stream_manager::check_finished_kernel()
{
-
- unsigned grid_uid = m_gpu->finished_kernel();
- bool check=register_finished_kernel(grid_uid);
- return check;
-
+ unsigned grid_uid = m_gpu->finished_kernel();
+ bool check=register_finished_kernel(grid_uid);
+ return check;
}
bool stream_manager::register_finished_kernel(unsigned grid_uid)
@@ -226,13 +224,17 @@ bool stream_manager::register_finished_kernel(unsigned grid_uid)
CUstream_st *stream = m_grid_id_to_stream[grid_uid];
kernel_info_t *kernel = stream->front().get_kernel();
assert( grid_uid == kernel->get_uid() );
- stream->record_next_done();
- m_grid_id_to_stream.erase(grid_uid);
- delete kernel;
- return true;
- }else{
- return false;
+
+ //Jin: should check children kernels for CDP
+ if(kernel->is_finished()) {
+ stream->record_next_done();
+ m_grid_id_to_stream.erase(grid_uid);
+ kernel->notify_parent_finished();
+ delete kernel;
+ return true;
+ }
}
+
return false;
}
@@ -259,21 +261,22 @@ stream_operation stream_manager::front()
{
// called by gpu simulation thread
stream_operation result;
- if( concurrent_streams_empty() )
- m_service_stream_zero = true;
+// if( concurrent_streams_empty() )
+ m_service_stream_zero = true;
if( m_service_stream_zero ) {
- if( !m_stream_zero.empty() ) {
- if( !m_stream_zero.busy() ) {
+ if( !m_stream_zero.empty() && !m_stream_zero.busy() ) {
result = m_stream_zero.next();
if( result.is_kernel() ) {
unsigned grid_id = result.get_kernel()->get_uid();
m_grid_id_to_stream[grid_id] = &m_stream_zero;
}
- }
} else {
m_service_stream_zero = false;
}
- } else {
+ }
+
+ if(!m_service_stream_zero)
+ {
std::list<struct CUstream_st*>::iterator s;
for( s=m_streams.begin(); s != m_streams.end(); s++) {
CUstream_st *stream = *s;