summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLucy Liu <[email protected]>2020-07-03 13:09:18 -0700
committerLucy Liu <[email protected]>2020-07-03 13:09:18 -0700
commit52bee41cfea17f13e93cc1fb812c125fd44bac7b (patch)
tree5c1657b9bdae72a3958330e03bb0ea8683a7bea5 /src
parent708a249f854cedb08b0b5e494f45f2371f0525a6 (diff)
add activemask, bfind, vmin, and vmax implementations from Francois
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.h1
-rw-r--r--src/cuda-sim/cuda-sim.cc6
-rw-r--r--src/cuda-sim/instructions.cc137
-rw-r--r--src/cuda-sim/opcodes.def11
-rw-r--r--src/cuda-sim/ptx.l9
-rw-r--r--src/cuda-sim/ptx.y36
-rw-r--r--src/cuda-sim/ptx_ir.cc3
-rw-r--r--src/cuda-sim/ptx_ir.h3
-rw-r--r--src/cuda-sim/ptx_parser.cc5
9 files changed, 172 insertions, 39 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 46534ab..c6e3b43 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -1132,6 +1132,7 @@ class warp_inst_t : public inst_t {
void print(FILE *fout) const;
unsigned get_uid() const { return m_uid; }
unsigned get_schd_id() const { return m_scheduler_id; }
+ active_mask_t get_warp_active_mask() const { return m_warp_active_mask; }
protected:
unsigned m_uid;
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 75dd3c8..451feb5 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -346,11 +346,11 @@ void function_info::ptx_assemble() {
printf("GPGPU-Sim PTX: finding reconvergence points for \'%s\'...\n", m_name.c_str() );
create_basic_blocks();
connect_basic_blocks();
- bool modified = false;
+ bool modified = false;
do {
find_dominators();
find_idominators();
- modified = connect_break_targets();
+ modified = connect_break_targets();
} while (modified == true);
if ( g_debug_execution>=50 ) {
@@ -1741,7 +1741,7 @@ void ptx_thread_info::ptx_exec_inst(warp_inst_t &inst, unsigned lane_id) {
} else {
const ptx_instruction *pI_saved = pI;
ptx_instruction *pJ = NULL;
- if (pI->get_opcode() == VOTE_OP) {
+ if( pI->get_opcode() == VOTE_OP || pI->get_opcode() == ACTIVEMASK_OP ) {
pJ = new ptx_instruction(*pI);
*((warp_inst_t *)pJ) = inst; // copy active mask information
pI = pJ;
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index bf9a040..886c6c0 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -166,6 +166,7 @@ void inst_not_implemented(const ptx_instruction *pI);
ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo,
operand_info dstInfo, unsigned type,
ptx_thread_info *thread);
+void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code);
void sign_extend(ptx_reg_t &data, unsigned src_size, const operand_info &dst);
@@ -1709,8 +1710,40 @@ void bfi_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
}
thread->set_operand_value(dst, data, i_type, thread, pI);
}
-void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
- inst_not_implemented(pI);
+void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread)
+{
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const unsigned i_type = pI->get_type();
+
+ const ptx_reg_t src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ const int msb = ( i_type == U32_TYPE || i_type == S32_TYPE) ? 31 : 63;
+
+ unsigned long a = 0;
+ switch (i_type)
+ {
+ case S32_TYPE: a = src1_data.s32; break;
+ case U32_TYPE: a = src1_data.u32; break;
+ case S64_TYPE: a = src1_data.s64; break;
+ case U64_TYPE: a = src1_data.u64; break;
+ default: assert(false); abort();
+ }
+
+ // negate negative signed inputs
+ if ( ( i_type == S32_TYPE || i_type == S64_TYPE ) && ( a & ( 1 << msb ) ) ) {
+ a = ~a;
+ }
+ uint32_t d_data = 0xffffffff;
+ for (uint32_t i = msb; i >= 0; i--) {
+ if (a & (1<<i)) { d_data = i; break; }
+ }
+
+ // if (.shiftamt && d != 0xffffffff) { d = msb - d; }
+
+ // store d
+ thread->set_operand_value(dst, d_data, U32_TYPE, thread, pI);
+
+
}
void bra_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
@@ -6301,11 +6334,17 @@ void vadd_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
void vmad_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
inst_not_implemented(pI);
}
-void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
- inst_not_implemented(pI);
+
+#define VMAX 0
+#define VMIN 1
+
+void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread)
+{
+ video_mem_instruction(pI, thread, VMAX);
}
-void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
- inst_not_implemented(pI);
+void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread)
+{
+ video_mem_instruction(pI, thread, VMIN);
}
void vset_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
inst_not_implemented(pI);
@@ -6400,6 +6439,15 @@ void vote_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
}
}
+void activemask_impl( const ptx_instruction *pI, ptx_thread_info *thread )
+{
+ active_mask_t l_activemask_bitset = pI->get_warp_active_mask();
+ uint32_t l_activemask_uint = static_cast<uint32_t>(l_activemask_bitset.to_ulong());
+
+ const operand_info &dst = pI->dst();
+ thread->set_operand_value(dst, l_activemask_uint, U32_TYPE, thread, pI);
+}
+
void xor_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
ptx_reg_t src1_data, src2_data, data;
@@ -6477,3 +6525,80 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo,
return result;
}
+
+void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code)
+{
+ const operand_info &dst = pI->dst(); // d
+ const operand_info &src1 = pI->src1(); // a
+ const operand_info &src2 = pI->src2(); // b
+ const operand_info &src3 = pI->src3(); // c
+
+ const unsigned i_type = pI->get_type();
+
+ std::list<int> scalar_type;
+ std::list<int> options;
+
+ ptx_reg_t a, b, ta, tb, c, data;
+
+ a = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ b = thread->get_operand_value(src2, dst, i_type, thread, 1);
+ c = thread->get_operand_value(src3, dst, i_type, thread, 1);
+
+ // TODO: implement this
+ // ta = partSelectSignExtend( a, atype );
+ // tb = partSelectSignExtend( b, btype );
+ ta = a;
+ tb = b;
+
+ options = pI->get_options();
+ assert(options.size() == 1);
+
+ auto option = options.begin();
+ assert(*option == ATOMIC_MAX || *option == ATOMIC_MIN);
+
+ switch ( i_type ) {
+ case S32_TYPE: {
+ // assert all operands are S32_TYPE:
+ scalar_type = pI->get_scalar_type();
+ for (auto scalar : scalar_type)
+ {
+ assert(scalar == S32_TYPE);
+ }
+ assert(scalar_type.size() == 3);
+ scalar_type.clear();
+
+ switch (op_code)
+ {
+ case VMAX:
+ data.s32 = MY_MAX_I(ta.s32, tb.s32);
+ break;
+ case VMIN:
+ data.s32 = MY_MIN_I(ta.s32, tb.s32);
+ break;
+ default:
+ assert(0);
+ }
+
+ switch (*option)
+ {
+ case ATOMIC_MAX:
+ data.s32 = MY_MAX_I(data.s32, c.s32);
+ break;
+ case ATOMIC_MIN:
+ data.s32 = MY_MIN_I(data.s32, c.s32);
+ break;
+ default:
+ assert(0); // not yet implemented
+ }
+ break;
+
+ }
+ default:
+ assert(0); // not yet implemented
+ }
+
+ thread->set_operand_value(dst, data, i_type, thread, pI);
+
+ return;
+}
+
diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def
index c4d6a83..aa85512 100644
--- a/src/cuda-sim/opcodes.def
+++ b/src/cuda-sim/opcodes.def
@@ -1,10 +1,10 @@
-// Copyright (c) 2009-2011, Tor M. Aamodt, Ali Bakhoda
+// Copyright (c) 2009-2011, Tor M. Aamodt, Ali Bakhoda
// The University of British Columbia
// All rights reserved.
-//
+//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
-//
+//
// Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
@@ -13,7 +13,7 @@
// Neither the name of The University of British Columbia nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
-//
+//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -27,7 +27,7 @@
/*6th operand of each OP_DEF reflects its classification */
-/*Type
+/*Type
ALU 1
MAD 2
Control 3
@@ -129,6 +129,7 @@ OP_DEF(VSHL_OP,vshl_impl,"vshl",0,11)
OP_DEF(VSHR_OP,vshr_impl,"vshr",0,11)
OP_DEF(VSUB_OP,vsub_impl,"vsub",0,11)
OP_DEF(VOTE_OP,vote_impl,"vote",0,3)
+OP_DEF(ACTIVEMASK_OP,activemask_impl,"activemask",1,3)
OP_DEF(XOR_OP,xor_impl,"xor",1,1)
OP_DEF(NOP_OP,nop_impl,"nop",0,7)
OP_DEF(BREAK_OP,break_impl,"break",0,3)
diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l
index 2dadda4..3592501 100644
--- a/src/cuda-sim/ptx.l
+++ b/src/cuda-sim/ptx.l
@@ -158,6 +158,7 @@ vshl TC; yylval->int_value = VSHL_OP; return OPCODE;
vshr TC; yylval->int_value = VSHR_OP; return OPCODE;
vsub TC; yylval->int_value = VSUB_OP; return OPCODE;
vote TC; yylval->int_value = VOTE_OP; return OPCODE;
+activemask TC; yylval->int_value = ACTIVEMASK_OP; return OPCODE;
xor TC; yylval->int_value = XOR_OP; return OPCODE;
nop TC; yylval->int_value = NOP_OP; return OPCODE;
break TC; yylval->int_value = BREAK_OP; return OPCODE;
@@ -252,7 +253,7 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE;
[$%][a-zA-Z0-9_$]+ TC; yylval->string_value = strdup(yytext); return IDENTIFIER;
[0-9]+\.[0-9]+ TC; sscanf(yytext,"%lf", &yylval->double_value); return DOUBLE_OPERAND;
-
+
0[xX][0-9a-fA-F]+U? TC; CHECK_UNSIGNED; sscanf(yytext,"%x", &yylval->int_value); return INT_OPERAND;
0[0-7]+U? TC; printf("GPGPU-Sim: ERROR ** parsing octal not (yet) implemented\n"); abort(); return INT_OPERAND;
0[bB][01]+U? TC; printf("GPGPU-Sim: ERROR ** parsing binary not (yet) implemented\n"); abort(); return INT_OPERAND;
@@ -438,9 +439,9 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE;
"*/" BEGIN(INITIAL);
"CPTX_BEGIN" printf("BEGINNING CUSTOM PTX.\n"); BEGIN(INITIAL);
[^C*\n]+ // eat comment in chunks
-"C" // eat the lone C
+"C" // eat the lone C
"*" // eat the lone star
-\n TC;
+\n TC;
}
<INITIAL>{
@@ -470,7 +471,7 @@ int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s )
if( recognizer->linebuf[i] == '\t' ) printf("\t");
else printf(" ");
}
-
+
printf("^\n\n");
fflush(stdout);
//exit(1);
diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y
index b38f783..90accc9 100644
--- a/src/cuda-sim/ptx.y
+++ b/src/cuda-sim/ptx.y
@@ -50,8 +50,8 @@ class ptx_recognizer;
%token <string_value> STRING
%token <int_value> OPCODE
%token <int_value> WMMA_DIRECTIVE
-%token <int_value> LAYOUT
-%token <int_value> CONFIGURATION
+%token <int_value> LAYOUT
+%token <int_value> CONFIGURATION
%token ALIGN_DIRECTIVE
%token BRANCHTARGETS_DIRECTIVE
%token BYTE_DIRECTIVE
@@ -295,7 +295,7 @@ ptr_space_spec: GLOBAL_DIRECTIVE { recognizer->add_ptr_spec(global_space); }
ptr_align_spec: ALIGN_DIRECTIVE INT_OPERAND
-statement_block: LEFT_BRACE statement_list RIGHT_BRACE
+statement_block: LEFT_BRACE statement_list RIGHT_BRACE
statement_list: directive_statement { recognizer->add_directive(); }
| statement_list prototype_block {printf("Prototype statement detected. WARNING: this is not supported yet on GPGPU-SIM\n"); }
@@ -315,7 +315,7 @@ directive_statement: variable_declaration SEMI_COLON
| TARGET_DIRECTIVE IDENTIFIER { recognizer->target_header($2); }
| FILE_DIRECTIVE INT_OPERAND STRING { recognizer->add_file($2,$3); }
| FILE_DIRECTIVE INT_OPERAND STRING COMMA INT_OPERAND COMMA INT_OPERAND { recognizer->add_file($2,$3); }
- | LOC_DIRECTIVE INT_OPERAND INT_OPERAND INT_OPERAND
+ | LOC_DIRECTIVE INT_OPERAND INT_OPERAND INT_OPERAND
| PRAGMA_DIRECTIVE STRING SEMI_COLON { recognizer->add_pragma($2); }
| function_decl SEMI_COLON {/*Do nothing*/}
;
@@ -336,7 +336,7 @@ identifier_spec: IDENTIFIER { recognizer->add_identifier($1,0,NON_ARRAY_IDENTIFI
int i,lbase,l;
char *id = NULL;
lbase = strlen($1);
- for( i=0; i < $3; i++ ) {
+ for( i=0; i < $3; i++ ) {
l = lbase + (int)log10(i+1)+10;
id = (char*) malloc(l);
snprintf(id,l,"%s%u",$1,i);
@@ -348,10 +348,10 @@ identifier_spec: IDENTIFIER { recognizer->add_identifier($1,0,NON_ARRAY_IDENTIFI
| IDENTIFIER LEFT_SQUARE_BRACKET INT_OPERAND RIGHT_SQUARE_BRACKET { recognizer->add_identifier($1,$3,ARRAY_IDENTIFIER); recognizer->func_header_info($1); recognizer->func_header_info_int("[",$3); recognizer->func_header_info("]");}
;
-var_spec_list: var_spec
+var_spec_list: var_spec
| var_spec_list var_spec;
-var_spec: space_spec
+var_spec: space_spec
| type_spec
| align_spec
| VISIBLE_DIRECTIVE
@@ -376,8 +376,8 @@ addressable_spec: CONST_DIRECTIVE { recognizer->add_space_spec(const_space,$1);
| TEX_DIRECTIVE { recognizer->add_space_spec(tex_space,0); }
;
-type_spec: scalar_type
- | vector_spec scalar_type
+type_spec: scalar_type
+ | vector_spec scalar_type
;
vector_spec: V2_TYPE { recognizer->add_option(V2_TYPE); recognizer->func_header_info(".v2");}
@@ -417,14 +417,14 @@ literal_list: literal_operand
// TODO: This is currently hardcoded to handle and ignore one specific case
// that all prototype statements follow in the PTX from Pytorch. As a
-// workaround, this parses and ignores both the prototype declaration
-// and calling of the prototype (which conveniently comes right after the
-// declaration for all cases.) This should be changed to handle both
+// workaround, this parses and ignores both the prototype declaration
+// and calling of the prototype (which conveniently comes right after the
+// declaration for all cases.) This should be changed to handle both
// declaring the prototype, and actually calling it.
prototype_block: prototype_decl prototype_call
-prototype_decl: IDENTIFIER COLON CALLPROTOTYPE_DIRECTIVE LEFT_PAREN prototype_param RIGHT_PAREN IDENTIFIER LEFT_PAREN prototype_param RIGHT_PAREN SEMI_COLON
-
+prototype_decl: IDENTIFIER COLON CALLPROTOTYPE_DIRECTIVE LEFT_PAREN prototype_param RIGHT_PAREN IDENTIFIER LEFT_PAREN prototype_param RIGHT_PAREN SEMI_COLON
+
prototype_call: OPCODE LEFT_PAREN IDENTIFIER RIGHT_PAREN COMMA operand COMMA LEFT_PAREN IDENTIFIER RIGHT_PAREN COMMA IDENTIFIER SEMI_COLON
| OPCODE IDENTIFIER COMMA LEFT_PAREN IDENTIFIER RIGHT_PAREN COMMA IDENTIFIER SEMI_COLON
@@ -439,7 +439,7 @@ instruction_statement: instruction SEMI_COLON
instruction: opcode_spec LEFT_PAREN operand RIGHT_PAREN { recognizer->set_return(); } COMMA operand COMMA LEFT_PAREN operand_list RIGHT_PAREN
| opcode_spec operand COMMA LEFT_PAREN operand_list RIGHT_PAREN
| opcode_spec operand COMMA LEFT_PAREN RIGHT_PAREN
- | opcode_spec operand_list
+ | opcode_spec operand_list
| opcode_spec
;
@@ -468,8 +468,8 @@ option: type_spec
| compare_spec
| addressable_spec
| rounding_mode
- | wmma_spec
- | prmt_spec
+ | wmma_spec
+ | prmt_spec
| SYNC_OPTION { recognizer->add_option(SYNC_OPTION); }
| ARRIVE_OPTION { recognizer->add_option(ARRIVE_OPTION); }
| RED_OPTION { recognizer->add_option(RED_OPTION); }
@@ -609,7 +609,7 @@ vector_operand: LEFT_BRACE IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { recognizer-
;
tex_operand: LEFT_SQUARE_BRACKET IDENTIFIER COMMA { recognizer->add_scalar_operand($2); }
- vector_operand
+ vector_operand
RIGHT_SQUARE_BRACKET
;
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index aa1c25a..e5b5fb7 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -1147,7 +1147,8 @@ static std::list<operand_info> check_operands(
const std::list<operand_info> &operands, gpgpu_context *ctx) {
static int g_warn_literal_operands_two_type_inst;
if ((opcode == CVT_OP) || (opcode == SET_OP) || (opcode == SLCT_OP) ||
- (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP)) {
+ (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP) ||
+ (opcode == VMIN_OP) || (opcode == VMAX_OP) ) {
// just make sure these do not have have const operands...
if (!g_warn_literal_operands_two_type_inst) {
std::list<operand_info>::const_iterator o;
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index 6627847..26283a6 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -965,6 +965,9 @@ class ptx_instruction : public warp_inst_t {
bool get_pred_neg() const { return m_neg_pred; }
int get_pred_mod() const { return m_pred_mod; }
const char *get_source() const { return m_source.c_str(); }
+
+ const std::list<int> get_scalar_type() const {return m_scalar_type;}
+ const std::list<int> get_options() const {return m_options;}
typedef std::vector<operand_info>::const_iterator const_iterator;
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc
index 3ae8de3..549c08c 100644
--- a/src/cuda-sim/ptx_parser.cc
+++ b/src/cuda-sim/ptx_parser.cc
@@ -624,8 +624,9 @@ void ptx_recognizer::add_scalar_type_spec(int type_spec) {
parse_assert((g_opcode == -1) || (g_opcode == CVT_OP) ||
(g_opcode == SET_OP) || (g_opcode == SLCT_OP) ||
(g_opcode == TEX_OP) || (g_opcode == MMA_OP) ||
- (g_opcode == DP4A_OP),
- "only cvt, set, slct, tex and dp4a can have more than one "
+ (g_opcode == DP4A_OP) || (g_opcode == VMIN_OP) ||
+ (g_opcode == VMAX_OP),
+ "only cvt, set, slct, tex, vmin, vmax and dp4a can have more than one "
"type specifier.");
}
g_scalar_type_spec = type_spec;