summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cuda-kernels/v4p_kernel.cu232
-rw-r--r--src/cuda-sim/instructions.cc91
-rw-r--r--src/cuda-sim/ptx.l7
-rw-r--r--src/cuda-sim/ptx.y16
-rw-r--r--src/cuda-sim/ptx_ir.cc25
-rw-r--r--src/cuda-sim/ptx_ir.h2
-rw-r--r--src/cuda-sim/ptx_parser.cc2
7 files changed, 362 insertions, 13 deletions
diff --git a/cuda-kernels/v4p_kernel.cu b/cuda-kernels/v4p_kernel.cu
new file mode 100644
index 0000000..bb9064b
--- /dev/null
+++ b/cuda-kernels/v4p_kernel.cu
@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <curand.h>
+
+// Define some error checking macros.
+#define cudaErrCheck(stat) { cudaErrCheck_((stat), __FILE__, __LINE__); }
+void cudaErrCheck_(cudaError_t stat, const char *file, int line) {
+ if (stat != cudaSuccess) {
+ fprintf(stderr, "CUDA Error: %s %s %d\n", cudaGetErrorString(stat), file, line);
+ }
+}
+
+#define curandErrCheck(stat) { curandErrCheck_((stat), __FILE__, __LINE__); }
+void curandErrCheck_(curandStatus_t stat, const char *file, int line) {
+ if (stat != CURAND_STATUS_SUCCESS) {
+ fprintf(stderr, "cuRand Error: %d %s %d\n", stat, file, line);
+ }
+}
+
+#include <mma.h>
+using namespace nvcuda;
+
+// Must be multiples of 16 for wmma code to work
+#define MATRIX_M (16)
+#define MATRIX_N (16)
+#define MATRIX_K (16)
+
+
+// The only dimensions currently supported by WMMA
+const int WMMA_M = 16;
+const int WMMA_N = 16;
+const int WMMA_K = 16;
+
+__global__ void wmma_example(half *a, half *b, float *c,float *d_fp16, int M, int N, int K) {
+ //unsigned int start_time=0,end_time=0;
+ //start_time=clock();
+
+ // Declare the fragments
+ wmma::fragment<wmma::matrix_a, WMMA_M, WMMA_N, WMMA_K, half, wmma::col_major> a_frag;
+ wmma::fragment<wmma::matrix_b, WMMA_M, WMMA_N, WMMA_K, half, wmma::col_major> b_frag;
+ wmma::fragment<wmma::accumulator, WMMA_M, WMMA_N, WMMA_K, float> c_frag;
+
+ // Bounds checking
+ wmma::load_matrix_sync(a_frag, a, K);
+ wmma::load_matrix_sync(b_frag, b, K);
+ wmma::load_matrix_sync(c_frag, c, N,wmma::mem_col_major);
+ wmma::mma_sync(c_frag, a_frag, b_frag, c_frag);
+
+ wmma::store_matrix_sync(d_fp16, c_frag, N, wmma::mem_col_major);
+ //printf("clock=%d",end_time-start_time);
+}
+
+__global__ void convertFp32ToFp16 (half *out, float *in, int n) {
+ int idx = blockDim.x * blockIdx.x + threadIdx.x;
+ if (idx < n) {
+ out[idx] = in[idx];
+ }
+}
+__global__ void convertFp16ToFp32 (float *out, half *in, int n) {
+ int idx = blockDim.x * blockIdx.x + threadIdx.x;
+ if (idx < n) {
+ out[idx] = in[idx];
+ }
+}
+
+__global__ void convertInt32ToInt8 (int *out, int *in, int n) {
+ int idx = blockDim.x * blockIdx.x + threadIdx.x;
+ if (idx < n/4) {
+ out[idx] =(in[4*idx]&0xff)|(in[4*idx+1]&0xff)<<8|(in[4*idx+2]&0xff)<<16|(in[4*idx+3]&0xff)<<24;
+ }
+}
+
+__global__ void convertInt8ToInt32 (int *out, int *in, int n) {
+ int idx = blockDim.x * blockIdx.x + threadIdx.x;
+ int shft_amt=8*(idx%4);
+ int shft_mask=0xff<<shft_amt;
+ if (idx < n) {
+ out[idx]= (in[idx/4]&shft_mask)>>shft_amt;
+ }
+}
+
+int main(int argc, char* argv[]) {
+ int *a_int32;
+ int *b_int32;
+ int *c_int32;
+ int *d_int32;
+
+ int *a_int8;
+ int *b_int8;
+
+ int *a_host_wmma;
+ int *b_host_wmma;
+ int *c_host_wmma;
+ int *d_host_wmma;
+ int *d_cal_host_wmma;
+
+ cudaEvent_t startWMMA;
+ cudaEvent_t stopWMMA;
+
+
+ cudaErrCheck(cudaEventCreate(&startWMMA));
+ cudaErrCheck(cudaEventCreate(&stopWMMA));
+
+ // Use tensor cores
+ cudaErrCheck(cudaMalloc((void**)&a_int32, MATRIX_M * MATRIX_K * sizeof(int)));
+ cudaErrCheck(cudaMalloc((void**)&b_int32, MATRIX_K * MATRIX_N * sizeof(int)));
+ cudaErrCheck(cudaMalloc((void**)&c_int32, MATRIX_K * MATRIX_N * sizeof(int)));
+ cudaErrCheck(cudaMalloc((void**)&d_int32, MATRIX_K * MATRIX_N * sizeof(int)));
+ cudaErrCheck(cudaMalloc((void**)&a_int8, MATRIX_M * MATRIX_K * sizeof(int)/4));
+ cudaErrCheck(cudaMalloc((void**)&b_int8, MATRIX_K * MATRIX_N * sizeof(int)/4));
+
+
+ a_host_wmma = (int *)malloc(MATRIX_M * MATRIX_K * sizeof(int));
+ b_host_wmma = (int *)malloc(MATRIX_K * MATRIX_N * sizeof(int));
+ c_host_wmma = (int *)malloc(MATRIX_M * MATRIX_N * sizeof(int));
+ d_host_wmma = (int *)malloc(MATRIX_M * MATRIX_N * sizeof(int));
+ d_cal_host_wmma = (int *)malloc(MATRIX_M * MATRIX_N * sizeof(int));
+
+ printf("a_int32\n");
+ for(int m=0;m<MATRIX_M;m++){
+ for(int n=0;n<MATRIX_K;n++){
+ a_host_wmma[m*MATRIX_K+n]=(m*MATRIX_K+n)%16;
+ printf("%d ",a_host_wmma[m*MATRIX_K+n]);
+ }
+ printf(";\n");
+ }
+
+ printf("b_int32\n");
+ for(int m=0;m<MATRIX_K;m++){
+ for(int n=0;n<MATRIX_N;n++){
+ b_host_wmma[m*MATRIX_N+n]=(m*MATRIX_N+n)%2;
+ printf("%d ",b_host_wmma[m*MATRIX_N+n]);
+ }
+ printf(";\n");
+ }
+
+ printf("c_int32\n");
+ for(int m=0;m<MATRIX_M;m++){
+ for(int n=0;n<MATRIX_N;n++){
+ c_host_wmma[m*MATRIX_N+n]=(m*MATRIX_N+n)%2;
+ d_cal_host_wmma[m*MATRIX_N+n]=0;
+ printf("%d ",c_host_wmma[m*MATRIX_N+n]);
+ }
+ printf(";\n");
+ }
+ for(int m=0;m<MATRIX_M;m++){
+ for(int n=0;n<MATRIX_N;n++){
+ for(int k=0;k<MATRIX_K;k++){
+ d_cal_host_wmma[m*MATRIX_N+n]+= a_host_wmma[m*MATRIX_K+k]*b_host_wmma[k*MATRIX_K+n];
+ }
+ d_cal_host_wmma[m*MATRIX_N+n]+=c_host_wmma[m*MATRIX_N+n];
+ }
+ }
+
+
+ cudaErrCheck(cudaMemcpy(a_int32,a_host_wmma, MATRIX_M * MATRIX_K * sizeof(int), cudaMemcpyHostToDevice));
+ cudaErrCheck(cudaMemcpy(b_int32,b_host_wmma, MATRIX_K * MATRIX_N * sizeof(int), cudaMemcpyHostToDevice));
+ cudaErrCheck(cudaMemcpy(c_int32,c_host_wmma, MATRIX_M * MATRIX_N * sizeof(int), cudaMemcpyHostToDevice));
+
+ convertInt32ToInt8 <<< (MATRIX_M * MATRIX_K + 255) / 256, 256 >>> (a_int8, a_int32, MATRIX_M * MATRIX_K);
+ convertInt8ToInt32 <<< (MATRIX_M * MATRIX_K + 255) / 256, 256 >>> (d_int32, a_int8, MATRIX_M * MATRIX_K);
+ //convertFp32ToFp16 <<< (MATRIX_K * MATRIX_N + 255) / 256, 256 >>> (b_fp16, b_fp32, MATRIX_K * MATRIX_N);
+ //convertFp32ToFp16 <<< (MATRIX_M * MATRIX_N + 255) / 256, 256 >>> (c_fp16, c_fp32, MATRIX_K * MATRIX_N);
+ cudaErrCheck(cudaMemcpy(d_host_wmma, d_int32, MATRIX_M * MATRIX_N * sizeof(float), cudaMemcpyDeviceToHost));
+
+
+//AAMIR printf("\nM = %d, N = %d, K = %d. \n", MATRIX_M, MATRIX_N, MATRIX_K);
+//AAMIR
+//AAMIR printf("Running with wmma...\n");
+//AAMIR cudaErrCheck(cudaEventRecord(startWMMA));
+//AAMIR wmma_example <<< 1, 32>>> (a_fp16, b_fp16, c_fp32, d_fp32 , MATRIX_M, MATRIX_N, MATRIX_K);
+//AAMIR cudaErrCheck(cudaEventRecord(stopWMMA));
+//AAMIR cudaErrCheck(cudaEventSynchronize(stopWMMA));
+//AAMIR
+//AAMIR // Error checking
+//AAMIR printf("\nChecking results...\n");
+//AAMIR cudaErrCheck(cudaMemcpy(d_host_wmma, d_fp32, MATRIX_M * MATRIX_N * sizeof(float), cudaMemcpyDeviceToHost));
+//AAMIR
+//AAMIR printf("Results verified: cublas and WMMA agree.\n\n");
+//AAMIR float wmmaTime;
+//AAMIR cudaErrCheck(cudaEventElapsedTime(&wmmaTime, startWMMA, stopWMMA));
+//AAMIR printf("wmma took %fms\n", wmmaTime);
+//AAMIR
+//AAMIR cudaErrCheck(cudaEventDestroy(startWMMA));
+//AAMIR cudaErrCheck(cudaEventDestroy(stopWMMA));
+//AAMIR
+//AAMIR int t=200000;
+//AAMIR while(t-->0);
+//AAMIR printf("D_CALCULATED\n");
+//AAMIR
+//AAMIR for(int m=0;m<MATRIX_M;m++){
+//AAMIR for(int n=0;n<MATRIX_N;n++){
+//AAMIR printf("%.2f,",d_cal_host_wmma[m*MATRIX_N+n]);
+//AAMIR }
+//AAMIR printf("\n");
+//AAMIR }
+ printf("D_WMMA\n");
+ for(int m=0;m<MATRIX_M;m++){
+ for(int n=0;n<MATRIX_N;n++){
+ printf("%d,",d_host_wmma[m*MATRIX_N+n]);
+ }
+ printf("\n");
+ }
+//AAMIR int suc=1;
+//AAMIR for(int m=0;m<MATRIX_M;m++){
+//AAMIR for(int n=0;n<MATRIX_N;n++){
+//AAMIR if(abs(d_cal_host_wmma[m*MATRIX_N+n]-d_host_wmma[m*MATRIX_N+n])>1)
+//AAMIR {
+//AAMIR printf("ERROR:\n");
+//AAMIR suc=0;
+//AAMIR }
+//AAMIR }
+//AAMIR }
+//AAMIR if(suc==1)
+//AAMIR printf("COMPLETED_SUCCESSFULLY\n");
+//AAMIR
+
+ cudaErrCheck(cudaFree(a_int32));
+ cudaErrCheck(cudaFree(b_int32));
+ cudaErrCheck(cudaFree(c_int32));
+ cudaErrCheck(cudaFree(d_int32));
+ cudaErrCheck(cudaFree(a_int8));
+ cudaErrCheck(cudaFree(b_int8));
+
+ free(a_host_wmma);
+ free(b_host_wmma);
+ free(c_host_wmma);
+ free(d_host_wmma);
+ cudaErrCheck(cudaDeviceReset());
+ return 0;
+}
+
+
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index 7af157f..aaee2a2 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -48,7 +48,7 @@
using half_float::half;
unsigned ptx_instruction::g_num_ptx_inst_uid=0;
-bool g_debug_instruction = 1;
+bool g_debug_instruction = 0;
const char *g_opcode_string[NUM_OPCODES] = {
@@ -3911,7 +3911,94 @@ void popc_impl( const ptx_instruction *pI, ptx_thread_info *thread )
}
void prefetch_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
void prefetchu_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
-void prmt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
+
+int prmt_mode_present(int mode)
+{
+ int returnval=0;
+ switch(mode){
+ case PRMT_F4E_MODE:
+ case PRMT_B4E_MODE:
+ case PRMT_RC8_MODE:
+ case PRMT_RC16_MODE:
+ case PRMT_ECL_MODE:
+ case PRMT_ECR_MODE:
+ returnval=1;
+ break;
+ default:
+ break;
+ }
+ return returnval;
+}
+int read_byte(int mode,int control,int d_sel_index,signed long long value){
+
+ int returnval;
+ int prmt_f4e_mode[4][4]={{0,1,2,3},{1,2,3,4},{2,3,4,5},{3,4,5,6}};
+ int prmt_b4e_mode[4][4]={{0,7,6,5},{1,0,7,6},{2,1,0,7},{3,2,1,0}};
+ int prmt_rc8_mode[4][4]={{0,0,0,0},{1,1,1,1},{2,2,2,2},{3,3,3,3}};
+ int prmt_ecl_mode[4][4]={{0,1,2,3},{1,1,2,3},{2,2,2,3},{3,3,3,3}};
+ int prmt_ecr_mode[4][4]={{0,0,0,0},{0,1,1,1},{0,1,2,2},{0,1,2,3}};
+ int prmt_rc16_mode[4][4]={{0,1,0,1},{2,3,2,3},{0,1,0,1},{2,3,2,3}};
+
+ if(!prmt_mode_present(mode)){
+ if(control&0x8){
+ returnval=0xff;
+ }
+ else{
+ returnval= (value>>(8*control)) & 0xff;
+ }
+ }
+ else{
+ switch(mode){
+ case PRMT_F4E_MODE: returnval=prmt_f4e_mode[control][d_sel_index];break;
+ case PRMT_B4E_MODE: returnval=prmt_b4e_mode[control][d_sel_index];break;
+ case PRMT_RC8_MODE: returnval=prmt_rc8_mode[control][d_sel_index];break;
+ case PRMT_ECL_MODE: returnval=prmt_ecl_mode[control][d_sel_index];break;
+ case PRMT_ECR_MODE: returnval=prmt_ecr_mode[control][d_sel_index];break;
+ case PRMT_RC16_MODE: returnval=prmt_rc16_mode[control][d_sel_index];break;
+ default: printf("ERROR\n");break;
+ }
+ }
+ return (returnval<<8*d_sel_index);
+}
+
+void prmt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) {
+
+ ptx_reg_t src1_data, src2_data, src3_data,tmpdata,data;
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const operand_info &src2 = pI->src2();
+ const operand_info &src3 = pI->src3();
+
+ unsigned mode = pI->prmt_op();
+ unsigned i_type = pI->get_type();
+
+ src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ src2_data = thread->get_operand_value(src2, dst, i_type, thread, 1);
+ src3_data = thread->get_operand_value(src3, dst, i_type, thread, 1);
+
+ tmpdata.s64=src1_data.s32|(src2_data.s64<<32);
+ int ctl[4];
+
+ if(!prmt_mode_present(mode)){
+ ctl[0]=(src3_data.s32>>0)&0xf;
+ ctl[1]=(src3_data.s32>>4)&0xf;
+ ctl[2]=(src3_data.s32>>8)&0xf;
+ ctl[3]=(src3_data.s32>>12)&0xf;
+ }
+ else{
+ ctl[0]=ctl[1]=ctl[2]=ctl[3]=(src3_data.s32>>0)&0x3;
+ }
+
+ data.s32=0;
+ data.s32=data.s32|read_byte(mode,ctl[0],0,tmpdata.s64); //First byte-0
+ data.s32=data.s32|read_byte(mode,ctl[1],1,tmpdata.s64); //Second byte-1
+ data.s32=data.s32|read_byte(mode,ctl[2],2,tmpdata.s64); //Third byte-2
+ data.s32=data.s32|read_byte(mode,ctl[3],3,tmpdata.s64); //Fourth byte-3
+
+ thread->set_operand_value(dst,data, i_type, thread, pI);
+
+
+}
void rcp_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l
index 03d6838..a6b6fcc 100644
--- a/src/cuda-sim/ptx.l
+++ b/src/cuda-sim/ptx.l
@@ -164,7 +164,12 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE;
\.row TC; ptx_lval.int_value = ROW; return LAYOUT;
\.col TC; ptx_lval.int_value = COL; return LAYOUT;
\.m16n16k16 TC; ptx_lval.int_value = M16N16K16; return CONFIGURATION;
-
+\.f4e TC; return PRMT_F4E_MODE;
+\.b4e TC; return PRMT_B4E_MODE;
+\.rc8 TC; return PRMT_RC8_MODE;
+\.ecl TC; return PRMT_ECL_MODE;
+\.ecr TC; return PRMT_ECR_MODE;
+\.rc16 TC; return PRMT_RC16_MODE;
\.align TC; return ALIGN_DIRECTIVE;
\.branchtargets TC; return BRANCHTARGETS_DIRECTIVE;
diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y
index 8744663..cd455dd 100644
--- a/src/cuda-sim/ptx.y
+++ b/src/cuda-sim/ptx.y
@@ -50,7 +50,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%token PTR_DIRECTIVE
%token ENTRY_DIRECTIVE
%token EXTERN_DIRECTIVE
-%token WEAK_DIRECTIVE
%token FILE_DIRECTIVE
%token FUNC_DIRECTIVE
%token GLOBAL_DIRECTIVE
@@ -203,6 +202,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%token DOWN_OPTION;
%token BFLY_OPTION;
%token IDX_OPTION;
+%token PRMT_F4E_MODE;
+%token PRMT_B4E_MODE;
+%token PRMT_RC8_MODE;
+%token PRMT_RC16_MODE;
+%token PRMT_ECL_MODE;
+%token PRMT_ECR_MODE;
%type <int_value> function_decl_header
%type <ptr_value> function_decl
@@ -432,6 +437,7 @@ option: type_spec
| addressable_spec
| rounding_mode
| wmma_spec
+ | prmt_spec
| SYNC_OPTION { add_option(SYNC_OPTION); }
| ARRIVE_OPTION { add_option(ARRIVE_OPTION); }
| RED_OPTION { add_option(RED_OPTION); }
@@ -520,6 +526,14 @@ compare_spec:EQ_OPTION { add_option(EQ_OPTION); }
| NAN_OPTION { add_option(NAN_OPTION); }
;
+prmt_spec: PRMT_F4E_MODE { add_option( PRMT_F4E_MODE); }
+ | PRMT_B4E_MODE { add_option( PRMT_B4E_MODE); }
+ | PRMT_RC8_MODE { add_option( PRMT_RC8_MODE); }
+ | PRMT_RC16_MODE{ add_option( PRMT_RC16_MODE);}
+ | PRMT_ECL_MODE { add_option( PRMT_ECL_MODE); }
+ | PRMT_ECR_MODE { add_option( PRMT_ECR_MODE); }
+ ;
+
wmma_spec: WMMA_DIRECTIVE LAYOUT CONFIGURATION{add_space_spec(global_space,0);add_ptr_spec(global_space); add_wmma_option($1);add_wmma_option($2);add_wmma_option($3);}
| WMMA_DIRECTIVE LAYOUT LAYOUT CONFIGURATION{add_wmma_option($1);add_wmma_option($2);add_wmma_option($3);add_wmma_option($4);}
;
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index 9c2ac69..d12c741 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -1233,16 +1233,25 @@ ptx_instruction::ptx_instruction( int opcode,
case HALF_OPTION:
m_inst_size = 4; // bytes
break;
- case EXTP_OPTION:
- break;
- case NC_OPTION:
- break;
- case UP_OPTION:
- case DOWN_OPTION:
- case BFLY_OPTION:
- case IDX_OPTION:
+ case EXTP_OPTION:
+ break;
+ case NC_OPTION:
+ break;
+ case UP_OPTION:
+ case DOWN_OPTION:
+ case BFLY_OPTION:
+ case IDX_OPTION:
m_shfl_op = last_ptx_inst_option;
break;
+
+ case PRMT_F4E_MODE:
+ case PRMT_B4E_MODE:
+ case PRMT_RC8_MODE:
+ case PRMT_ECL_MODE:
+ case PRMT_ECR_MODE:
+ case PRMT_RC16_MODE:
+ m_prmt_op = last_ptx_inst_option;
+ break;
default:
assert(0);
break;
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index cff312b..cb4556e 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -1086,6 +1086,7 @@ public:
unsigned dimension() const { return m_geom_spec;}
unsigned barrier_op() const {return m_barrier_op;}
unsigned shfl_op() const {return m_shfl_op;}
+ unsigned prmt_op() const {return m_prmt_op;}
enum vote_mode_t { vote_any, vote_all, vote_uni, vote_ballot };
enum vote_mode_t vote_mode() const { return m_vote_mode; }
@@ -1156,6 +1157,7 @@ private:
unsigned m_saturation_mode;
unsigned m_barrier_op;
unsigned m_shfl_op;
+ unsigned m_prmt_op;
std::list<int> m_scalar_type;
memory_space_t m_space_spec;
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc
index eb81961..6757091 100644
--- a/src/cuda-sim/ptx_parser.cc
+++ b/src/cuda-sim/ptx_parser.cc
@@ -39,7 +39,7 @@ void set_ptx_warp_size(const struct core_config * warp_size)
g_shader_core_config=warp_size;
}
-static bool g_debug_ir_generation=true;
+static bool g_debug_ir_generation=false;
const char *g_filename;
unsigned g_max_regs_per_thread = 0;