diff options
77 files changed, 4853 insertions, 3012 deletions
diff --git a/Jenkinsfile b/Jenkinsfile index 4bdbddf..a345bc0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -14,8 +14,8 @@ pipeline { sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/4.2_env_setup.sh &&\ source `pwd`/setup_environment &&\ make -j' - }, "9.1" : { - sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ + }, "10.1" : { + sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/10.1_env_setup.sh &&\ source `pwd`/setup_environment &&\ make -j' } @@ -24,7 +24,7 @@ pipeline { stage('simulations-build'){ steps{ sh 'rm -rf gpgpu-sim_simulations' - sh 'git clone [email protected]:gpgpu-sim/gpgpu-sim_simulations.git && \ + sh 'git clone [email protected]:purdue-aalp/gpgpu-sim_simulations.git && \ cd gpgpu-sim_simulations && \ git pull && \ ln -s /home/tgrogers-raid/a/common/data_dirs benchmarks/' @@ -34,7 +34,7 @@ pipeline { source ./benchmarks/src/setup_environment && \ make -j -C ./benchmarks/src rodinia_2.0-ft sdk-4.2 && \ make -C ./benchmarks/src data' - sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ + sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/10.1_env_setup.sh &&\ source `pwd`/setup_environment &&\ cd gpgpu-sim_simulations && \ source ./benchmarks/src/setup_environment && \ @@ -47,71 +47,58 @@ pipeline { parallel "4.2-rodinia": { sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/4.2_env_setup.sh &&\ source `pwd`/setup_environment &&\ - ./gpgpu-sim_simulations/util/job_launching/run_simulations.py -B rodinia_2.0-ft -C GTX480,GTX480-PTXPLUS -N regress-$$ && \ - PLOTDIR="jenkins/${JOB_NAME}/${BUILD_NUMBER}/4.2-rodinia" && ssh [email protected] mkdir -p /home/dynamo/a/tgrogers/website/gpgpu-sim-plots/$PLOTDIR && \ - ./gpgpu-sim_simulations/util/job_launching/monitor_func_test.py -v -N regress-$$ -s stats-per-app-4.2.csv && \ - ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c stats-per-app-4.2.csv -p [email protected]:~/website/gpgpu-sim-plots/$PLOTDIR -w https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/$PLOTDIR -n $PLOTDIR ' - }, "9.1-functest": { - sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ + export PTXAS_CUDA_INSTALL_PATH=/home/tgrogers-raid/a/common/cuda-10.1 &&\ + ./gpgpu-sim_simulations/util/job_launching/run_simulations.py -B rodinia_2.0-ft -C TITANV-PTXPLUS -N regress-$$ && \ + PLOTDIR="jenkins/${JOB_NAME}/${BUILD_NUMBER}/4.2" && ssh [email protected] mkdir -p /home/dynamo/a/tgrogers/website/gpgpu-sim-plots/$PLOTDIR && \ + ./gpgpu-sim_simulations/util/job_launching/monitor_func_test.py -v -N regress-$$ -s stats-per-app-4.2.csv' + }, "10.1-functest": { + sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/10.1_env_setup.sh &&\ source `pwd`/setup_environment &&\ ./gpgpu-sim_simulations/util/job_launching/run_simulations.py -B rodinia_2.0-ft,sdk-4.2 -C TITANV -N regress-$$ && \ - PLOTDIR="jenkins/${JOB_NAME}/${BUILD_NUMBER}/9.1-rodinia" && ssh [email protected] mkdir -p /home/dynamo/a/tgrogers/website/gpgpu-sim-plots/$PLOTDIR && \ - ./gpgpu-sim_simulations/util/job_launching/monitor_func_test.py -v -s stats-per-app-9.1.csv -N regress-$$ && \ - ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c stats-per-app-9.1.csv -p [email protected]:~/website/gpgpu-sim-plots/$PLOTDIR -w https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/$PLOTDIR -n $PLOTDIR' + PLOTDIR="jenkins/${JOB_NAME}/${BUILD_NUMBER}/10.1" && ssh [email protected] mkdir -p /home/dynamo/a/tgrogers/website/gpgpu-sim-plots/$PLOTDIR && \ + ./gpgpu-sim_simulations/util/job_launching/monitor_func_test.py -v -s stats-per-app-10.1.csv -N regress-$$' } } } - stage('4.2-correlate'){ + stage('correlate-delta-and-archive') { steps { - sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/4.2_env_setup.sh &&\ - source `pwd`/setup_environment &&\ - PLOTDIR="jenkins/${JOB_NAME}" &&\ - ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft -C GTX480,GTX480-PTXPLUS > stats-per-kernel-4.2.csv &&\ - ./gpgpu-sim_simulations/util/plotting/correlate_and_publish.sh stats-per-kernel-4.2.csv $PLOTDIR ${BUILD_NUMBER}' - } - } - stage('9.1-correlate'){ - steps { - sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ - source `pwd`/setup_environment &&\ - PLOTDIR="jenkins/${JOB_NAME}" &&\ - ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft,sdk-4.2 -C TITANV > stats-per-kernel-9.1.csv &&\ - ./gpgpu-sim_simulations/util/plotting/correlate_and_publish.sh stats-per-kernel-9.1.csv $PLOTDIR ${BUILD_NUMBER}' - } - } - stage('archive-and-delta') { - steps { - sh 'rm -rf gpgpu-sim-results-repo' + sh './gpgpu-sim_simulations/run_hw/get_hw_data.sh' + sh 'rm -rf ./gpgpu-sim_simulations/util/plotting/correl-html && rm -rf gpgpu-sim-results-repo && rm -rf ./gpgpu-sim_simulations/util/plotting/htmls' sh 'git clone [email protected]:purdue-aalp/gpgpu-sim-results-repo.git' sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/4.2_env_setup.sh &&\ - ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft -C GTX480-PTXPLUS > stats-per-kernel-4.2-ptxplus.csv &&\ - ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft -C GTX480 > stats-per-kernel-4.2-ptx.csv' - sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ - ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft,sdk-4.2 -C TITANV > stats-per-kernel-9.1-titanx.csv' - sh './gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/jenkins/quick-regress/AALP/gpgpu-sim_distribution/dev-purdue-integration/stats-per-app-4.2.csv,./stats-per-app-4.2.csv -R > per-app-merge-4.2.csv' - sh './gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/jenkins/quick-regress/AALP/gpgpu-sim_distribution/dev-purdue-integration/stats-per-app-9.1.csv,./stats-per-app-9.1.csv -R > per-app-merge-9.1.csv' + ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft -C TITANV-PTXPLUS -A > stats-per-kernel-4.2-ptxplus.csv' + sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/10.1_env_setup.sh &&\ + ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B rodinia_2.0-ft,sdk-4.2 -C TITANV -A > stats-per-kernel-10.1.csv' + sh 'if [ ! -d ./gpgpu-sim-results-repo/${JOB_NAME} ]; then mkdir -p ./gpgpu-sim-results-repo/${JOB_NAME}/ ; cp ./gpgpu-sim-results-repo/purdue-aalp/gpgpu-sim_distribution/dev/* ./gpgpu-sim-results-repo/${JOB_NAME}/ ; fi' + sh './gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/${JOB_NAME}/stats-per-app-4.2.csv,./stats-per-app-4.2.csv -R > per-app-merge-4.2.csv' + sh './gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/${JOB_NAME}/stats-per-app-10.1.csv,./stats-per-app-10.1.csv -R > per-app-merge-10.1.csv' sh 'PLOTDIR="jenkins/${JOB_NAME}" &&\ - ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c per-app-merge-4.2.csv -p [email protected]:~/website/gpgpu-sim-plots/$PLOTDIR/deltas -w https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/$PLOTDIR -n $PLOTDIR/deltas &&\ - ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c per-app-merge-9.1.csv -p [email protected]:~/website/gpgpu-sim-plots/$PLOTDIR/deltas -w https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/$PLOTDIR/deltas -n $PLOTDIR/deltas &&\ - ./gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/jenkins/quick-regress/AALP/gpgpu-sim_distribution/dev-purdue-integration/stats-per-kernel-4.2-ptx.csv,./stats-per-kernel-4.2-ptx.csv -R > per-kernel-merge-4.2-ptx.csv &&\ - ./gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/jenkins/quick-regress/AALP/gpgpu-sim_distribution/dev-purdue-integration/stats-per-kernel-4.2-ptxplus.csv,./stats-per-kernel-4.2-ptxplus.csv -R > per-kernel-merge-4.2-ptxplus.csv &&\ - ./gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/jenkins/quick-regress/AALP/gpgpu-sim_distribution/dev-purdue-integration/stats-per-kernel-9.1-titanx.csv,./stats-per-kernel-9.1-titanx.csv -R > per-kernel-merge-9.1-titanx.csv &&\ - ./gpgpu-sim_simulations/util/plotting/correlate_and_publish.sh per-kernel-merge-4.2-ptx.csv $PLOTDIR ${BUILD_NUMBER} &&\ - ./gpgpu-sim_simulations/util/plotting/correlate_and_publish.sh per-kernel-merge-4.2-ptxplus.csv $PLOTDIR ${BUILD_NUMBER} &&\ - ./gpgpu-sim_simulations/util/plotting/correlate_and_publish.sh per-kernel-merge-9.1-titanx.csv $PLOTDIR ${BUILD_NUMBER} &&\ - mkdir -p ./jenkins/quick-regress/${JOB_NAME}/ && cp stats-per-*.csv ./jenkins/quick-regress/${JOB_NAME}/ &&\ + ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c per-app-merge-4.2.csv -P cuda-4.2 &&\ + ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c per-app-merge-10.1.csv -P cuda-10.1 &&\ + ./gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/${JOB_NAME}/stats-per-kernel-4.2-ptxplus.csv,./stats-per-kernel-4.2-ptxplus.csv -R > per-kernel-merge-4.2-ptxplus.csv &&\ + ./gpgpu-sim_simulations/util/plotting/merge-stats.py -c ./gpgpu-sim-results-repo/${JOB_NAME}/stats-per-kernel-10.1.csv,./stats-per-kernel-10.1.csv -R > per-kernel-merge-10.1.csv &&\ + ./gpgpu-sim_simulations/util/plotting/plot-correlation.py -c per-kernel-merge-4.2-ptxplus.csv -p cuda-4.2 | grep "Correl=" | tee correl.4.2.txt &&\ + ./gpgpu-sim_simulations/util/plotting/plot-correlation.py -c per-kernel-merge-10.1.csv -p cuda-10.1 | grep "Correl=" | tee correl.10.1.txt &&\ + mkdir -p ./gpgpu-sim-results-repo/${JOB_NAME}/ && cp stats-per-*.csv ./gpgpu-sim-results-repo/${JOB_NAME}/ &&\ cd ./gpgpu-sim-results-repo &&\ - git diff --quiet && git diff --staged --quiet || git commit -am "Jenkins automated checkin ${BUILD_NUMBER}" &&\ + git diff --quiet && git diff --staged --quiet || git commit -am "Jenkins automated checkin ${JOB_NAME} Build:${BUILD_NUMBER}" &&\ git push' + + sh 'PLOTDIR="/home/dynamo/a/tgrogers/website/gpgpu-sim-plots/jenkins/${JOB_NAME}" &&\ + ssh [email protected] mkdir -p $PLOTDIR/${BUILD_NUMBER} && \ + scp ./gpgpu-sim_simulations/util/plotting/correl-html/* [email protected]:$PLOTDIR/${BUILD_NUMBER} &&\ + scp ./gpgpu-sim_simulations/util/plotting/htmls/* [email protected]:$PLOTDIR/${BUILD_NUMBER} &&\ + ssh [email protected] "cd $PLOTDIR && rm -rf latest && cp -r ${BUILD_NUMBER} latest"' } } } post { success { - emailext body: "See ${BUILD_URL}", + emailext body:'''${SCRIPT, template="groovy-html.success.template"}''', recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], subject: "[AALP Jenkins] Build #${BUILD_NUMBER} - Success!", + attachmentsPattern: 'correl.*.txt', to: '[email protected]' } failure { diff --git a/cuobjdump_to_ptxplus/Makefile b/cuobjdump_to_ptxplus/Makefile index 242a066..e95136a 100644 --- a/cuobjdump_to_ptxplus/Makefile +++ b/cuobjdump_to_ptxplus/Makefile @@ -27,11 +27,11 @@ $(OUTPUT_DIR)/cuobjdump_to_ptxplus: $(OUTPUT_DIR)/cuobjdumpInst.o $(OUTPUT_DIR)/ ${LD} ${LDFLAGS} -o $@ $(OUTPUT_DIR)/cuobjdumpInst.o $(OUTPUT_DIR)/cuobjdumpInstList.o $(OUTPUT_DIR)/cuobjdump_to_ptxplus.o $(PTX_PARSER_OBJECTS) $(SASS_PARSER_OBJECTS) $(ELF_PARSER_OBJECTS) $(HEADER_PARSER_OBJECTS) -$(OUTPUT_DIR)/lex.ptx_.c : ../src/cuda-sim/ptx.l - ${LEX} ${LEXFLAGS} -o$(OUTPUT_DIR)/lex.ptx_.c ../src/cuda-sim/ptx.l +$(OUTPUT_DIR)/lex.ptx_.c : ptx.l + ${LEX} ${LEXFLAGS} -o$(OUTPUT_DIR)/lex.ptx_.c ptx.l -$(OUTPUT_DIR)/ptx.tab.c : ../src/cuda-sim/ptx.y - ${YACC} ${YFLAGS} --name-prefix=ptx_ -v ../src/cuda-sim/ptx.y --file-prefix=$(OUTPUT_DIR)/ptx +$(OUTPUT_DIR)/ptx.tab.c : ptx.y + ${YACC} ${YFLAGS} --name-prefix=ptx_ -v ptx.y --file-prefix=$(OUTPUT_DIR)/ptx $(OUTPUT_DIR)/ptx.tab.h :$(OUTPUT_DIR)/ptx.tab.c diff --git a/cuobjdump_to_ptxplus/ptx.l b/cuobjdump_to_ptxplus/ptx.l new file mode 100644 index 0000000..3232361 --- /dev/null +++ b/cuobjdump_to_ptxplus/ptx.l @@ -0,0 +1,471 @@ +/* +Copyright (c) 2009-2011, Tor M. Aamodt +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 +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. +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 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +%option nounput +%option noyywrap +%option yylineno +%option prefix="ptx_" +%{ +#include "opcodes.h" +#include "ptx.tab.h" +#include <string.h> + +#define LINEBUF_SIZE (64*1024) +char linebuf[LINEBUF_SIZE]; +unsigned col = 0; +#define TC col+=strlen(ptx_text); +#define CHECK_UNSIGNED \ + if( yytext[strlen(yytext)-1]=='U' ) { \ + printf("GPGPU-Sim: ERROR ** U modifier not implemented\n"); \ + abort(); \ + } +int ptx_error( const char *s ); +%} + +%s IN_STRING +%s IN_COMMENT +%x IN_FUNC_DECL +%x NOT_OPCODE +%% + +abs TC; ptx_lval.int_value = ABS_OP; return OPCODE; +add TC; ptx_lval.int_value = ADD_OP; return OPCODE; +addp TC; ptx_lval.int_value = ADDP_OP; return OPCODE; +addc TC; ptx_lval.int_value = ADDC_OP; return OPCODE; +and TC; ptx_lval.int_value = AND_OP; return OPCODE; +andn TC; ptx_lval.int_value = ANDN_OP; return OPCODE; +atom TC; ptx_lval.int_value = ATOM_OP; return OPCODE; +bar.warp TC; ptx_lval.int_value = NOP_OP; return OPCODE; +bar TC; ptx_lval.int_value = BAR_OP; return OPCODE; +bfe TC; ptx_lval.int_value = BFE_OP; return OPCODE; +bfi TC; ptx_lval.int_value = BFI_OP; return OPCODE; +bfind TC; ptx_lval.int_value = BFIND_OP; return OPCODE; +bra TC; ptx_lval.int_value = BRA_OP; return OPCODE; +brx TC; ptx_lval.int_value = BRX_OP; return OPCODE; +brev TC; ptx_lval.int_value = BREV_OP; return OPCODE; +brkpt TC; ptx_lval.int_value = BRKPT_OP; return OPCODE; + +wmma TC; ptx_lval.int_value = MMA_OP; return OPCODE; +wmma\.load TC; ptx_lval.int_value = MMA_LD_OP; return OPCODE; +wmma\.store TC; ptx_lval.int_value = MMA_ST_OP; return OPCODE; + +call TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALL_OP; return OPCODE; // blocking opcode token in case the callee has the same name as an opcode +callp TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALLP_OP; return OPCODE; +clz TC; ptx_lval.int_value = CLZ_OP; return OPCODE; +cnot TC; ptx_lval.int_value = CNOT_OP; return OPCODE; +cos TC; ptx_lval.int_value = COS_OP; return OPCODE; +cvt TC; ptx_lval.int_value = CVT_OP; return OPCODE; +cvta TC; ptx_lval.int_value = CVTA_OP; return OPCODE; +div TC; ptx_lval.int_value = DIV_OP; return OPCODE; +dp4a TC; ptx_lval.int_value = DP4A_OP; return OPCODE; +ex2 TC; ptx_lval.int_value = EX2_OP; return OPCODE; +exit TC; ptx_lval.int_value = EXIT_OP; return OPCODE; +fma TC; ptx_lval.int_value = FMA_OP; return OPCODE; +isspacep TC; ptx_lval.int_value = ISSPACEP_OP; return OPCODE; +ld TC; ptx_lval.int_value = LD_OP; return OPCODE; +ld.volatile TC; ptx_lval.int_value = LD_OP; return OPCODE; +ldu TC; ptx_lval.int_value = LDU_OP; return OPCODE; +lg2 TC; ptx_lval.int_value = LG2_OP; return OPCODE; +mad24 TC; ptx_lval.int_value = MAD24_OP; return OPCODE; +mad TC; ptx_lval.int_value = MAD_OP; return OPCODE; +madc TC; ptx_lval.int_value = MADC_OP; return OPCODE; +madp TC; ptx_lval.int_value = MADP_OP; return OPCODE; +max TC; ptx_lval.int_value = MAX_OP; return OPCODE; +membar TC; ptx_lval.int_value = MEMBAR_OP; return OPCODE; +min TC; ptx_lval.int_value = MIN_OP; return OPCODE; +mov TC; ptx_lval.int_value = MOV_OP; return OPCODE; +mul24 TC; ptx_lval.int_value = MUL24_OP; return OPCODE; +mul TC; ptx_lval.int_value = MUL_OP; return OPCODE; +neg TC; ptx_lval.int_value = NEG_OP; return OPCODE; +nandn TC; ptx_lval.int_value = NANDN_OP; return OPCODE; +norn TC; ptx_lval.int_value = NORN_OP; return OPCODE; +not TC; ptx_lval.int_value = NOT_OP; return OPCODE; +or TC; ptx_lval.int_value = OR_OP; return OPCODE; +orn TC; ptx_lval.int_value = ORN_OP; return OPCODE; +pmevent TC; ptx_lval.int_value = PMEVENT_OP; return OPCODE; +popc TC; ptx_lval.int_value = POPC_OP; return OPCODE; +prefetch TC; ptx_lval.int_value = PREFETCH_OP; return OPCODE; +prefetchu TC; ptx_lval.int_value = PREFETCHU_OP; return OPCODE; +prmt TC; ptx_lval.int_value = PRMT_OP; return OPCODE; +rcp TC; ptx_lval.int_value = RCP_OP; return OPCODE; +red TC; ptx_lval.int_value = RED_OP; return OPCODE; +rem TC; ptx_lval.int_value = REM_OP; return OPCODE; +ret TC; ptx_lval.int_value = RET_OP; return OPCODE; +retp TC; ptx_lval.int_value = RETP_OP; return OPCODE; +rsqrt TC; ptx_lval.int_value = RSQRT_OP; return OPCODE; +sad TC; ptx_lval.int_value = SAD_OP; return OPCODE; +selp TC; ptx_lval.int_value = SELP_OP; return OPCODE; +setp TC; ptx_lval.int_value = SETP_OP; return OPCODE; +set TC; ptx_lval.int_value = SET_OP; return OPCODE; +shfl TC; ptx_lval.int_value = SHFL_OP; return OPCODE; +shl TC; ptx_lval.int_value = SHL_OP; return OPCODE; +shr TC; ptx_lval.int_value = SHR_OP; return OPCODE; +sin TC; ptx_lval.int_value = SIN_OP; return OPCODE; +slct TC; ptx_lval.int_value = SLCT_OP; return OPCODE; +sqrt TC; ptx_lval.int_value = SQRT_OP; return OPCODE; +sst TC; ptx_lval.int_value = SST_OP; return OPCODE; +ssy TC; ptx_lval.int_value = SSY_OP; return OPCODE; +st TC; ptx_lval.int_value = ST_OP; return OPCODE; +st.volatile TC; ptx_lval.int_value = ST_OP; return OPCODE; +sub TC; ptx_lval.int_value = SUB_OP; return OPCODE; +subc TC; ptx_lval.int_value = SUBC_OP; return OPCODE; +suld TC; ptx_lval.int_value = SULD_OP; return OPCODE; +sured TC; ptx_lval.int_value = SURED_OP; return OPCODE; +surst TC; ptx_lval.int_value = SUST_OP; return OPCODE; +suq TC; ptx_lval.int_value = SUQ_OP; return OPCODE; +tex TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = TEX_OP; return OPCODE; +txq TC; ptx_lval.int_value = TEX_OP; return OPCODE; +trap TC; ptx_lval.int_value = TRAP_OP; return OPCODE; +vabsdiff TC; ptx_lval.int_value = VABSDIFF_OP; return OPCODE; +vadd TC; ptx_lval.int_value = VADD_OP; return OPCODE; +vmad TC; ptx_lval.int_value = VMAD_OP; return OPCODE; +vmax TC; ptx_lval.int_value = VMAX_OP; return OPCODE; +vmin TC; ptx_lval.int_value = VMIN_OP; return OPCODE; +vset TC; ptx_lval.int_value = VSET_OP; return OPCODE; +vshl TC; ptx_lval.int_value = VSHL_OP; return OPCODE; +vshr TC; ptx_lval.int_value = VSHR_OP; return OPCODE; +vsub TC; ptx_lval.int_value = VSUB_OP; return OPCODE; +vote TC; ptx_lval.int_value = VOTE_OP; return OPCODE; +xor TC; ptx_lval.int_value = XOR_OP; return OPCODE; +nop TC; ptx_lval.int_value = NOP_OP; return OPCODE; +break TC; ptx_lval.int_value = BREAK_OP; return OPCODE; +breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; + +"CPTX_END" printf("ENDING CUSTOM PTX.\n"); BEGIN(IN_COMMENT); + +<INITIAL,NOT_OPCODE,IN_INST,IN_FUNC_DECL>{ +\.a\.sync TC; ptx_lval.int_value = LOAD_A; return WMMA_DIRECTIVE; +\.b\.sync TC; ptx_lval.int_value = LOAD_B; return WMMA_DIRECTIVE; +\.c\.sync TC; ptx_lval.int_value = LOAD_C; return WMMA_DIRECTIVE; +\.d\.sync TC; ptx_lval.int_value = STORE_D; return WMMA_DIRECTIVE; +\.mma\.sync TC;ptx_lval.int_value=MMA; return WMMA_DIRECTIVE; + +\.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; +\.byte TC; return BYTE_DIRECTIVE; /* not in PTX 2.1 */ +\.callprototype TC; return CALLPROTOTYPE_DIRECTIVE; +\.calltargets TC; return CALLTARGETS_DIRECTIVE; +\.const\[[0-9]+\] TC; ptx_lval.int_value = atoi(yytext+7); return CONST_DIRECTIVE; +\.const TC; ptx_lval.int_value = 0; return CONST_DIRECTIVE; +\.entry TC; return ENTRY_DIRECTIVE; +\.extern TC; return EXTERN_DIRECTIVE; +\.file TC; BEGIN(INITIAL); return FILE_DIRECTIVE; +\.func TC; BEGIN(IN_FUNC_DECL); return FUNC_DIRECTIVE; // blocking opcode parsing in case the function has the same name as an opcode (e.g. sin(), cos()) +\.global TC; return GLOBAL_DIRECTIVE; +\.global.volatile TC; return GLOBAL_DIRECTIVE; //TODO: fix this! +\.local TC; return LOCAL_DIRECTIVE; +\.loc TC; return LOC_DIRECTIVE; +\.maxnctapersm TC; return MAXNCTAPERSM_DIRECTIVE; +\.maxnreg TC; return MAXNNREG_DIRECTIVE; +\.maxntid TC; return MAXNTID_DIRECTIVE; +\.minnctapersm TC; return MINNCTAPERSM_DIRECTIVE; +\.param TC; return PARAM_DIRECTIVE; +\.pragma TC; return PRAGMA_DIRECTIVE; +\.reg TC; return REG_DIRECTIVE; +\.reqntid TC; return REQNTID_DIRECTIVE; +\.section TC; return SECTION_DIRECTIVE; +\.shared TC; return SHARED_DIRECTIVE; +\.sreg TC; return SREG_DIRECTIVE; +\.sstarr TC; return SSTARR_DIRECTIVE; +\.struct TC; return STRUCT_DIRECTIVE; +\.surf TC; return SURF_DIRECTIVE; /* not in PTX 2.1 */ +\.target TC; return TARGET_DIRECTIVE; +\.tex TC; BEGIN(NOT_OPCODE); return TEX_DIRECTIVE; +\.union TC; return UNION_DIRECTIVE; /* not in PTX 2.1 */ +\.version TC; return VERSION_DIRECTIVE; +\.visible TC; return VISIBLE_DIRECTIVE; +\.weak TC; return WEAK_DIRECTIVE; +\.address_size TC; return ADDRESS_SIZE_DIRECTIVE; +\.weak TC; return WEAK_DIRECTIVE; + +\.constptr TC; return CONSTPTR_DIRECTIVE; /* Ptx plus directive for pointer to constant memory */ +\.ptr TC; return PTR_DIRECTIVE; /* Added for new OpenCL genrated code */ + +"%clock" TC; ptx_lval.int_value = CLOCK_REG; return SPECIAL_REGISTER; +"%halfclock" TC; ptx_lval.int_value = HALFCLOCK_ID; return SPECIAL_REGISTER; +"%clock64" TC; ptx_lval.int_value = CLOCK64_REG; return SPECIAL_REGISTER; +"%ctaid" TC; ptx_lval.int_value = CTAID_REG; return SPECIAL_REGISTER; +"%envreg"[0-9]+ TC; sscanf(yytext+7,"%u",&ptx_lval.int_value); ptx_lval.int_value<<=16; ptx_lval.int_value += ENVREG_REG; return SPECIAL_REGISTER; +"%gridid" TC; ptx_lval.int_value = GRIDID_REG; return SPECIAL_REGISTER; +"%laneid" TC; ptx_lval.int_value = LANEID_REG; return SPECIAL_REGISTER; +"%lanemask_eq" TC; ptx_lval.int_value = LANEMASK_EQ_REG; return SPECIAL_REGISTER; +"%lanemask_le" TC; ptx_lval.int_value = LANEMASK_LE_REG; return SPECIAL_REGISTER; +"%lanemask_lt" TC; ptx_lval.int_value = LANEMASK_LT_REG; return SPECIAL_REGISTER; +"%lanemask_ge" TC; ptx_lval.int_value = LANEMASK_GE_REG; return SPECIAL_REGISTER; +"%lanemask_gt" TC; ptx_lval.int_value = LANEMASK_GT_REG; return SPECIAL_REGISTER; +"%nctaid" TC; ptx_lval.int_value = NCTAID_REG; return SPECIAL_REGISTER; +"%ntid" TC; ptx_lval.int_value = NTID_REG; return SPECIAL_REGISTER; +"%nsmid" TC; ptx_lval.int_value = NSMID_REG; return SPECIAL_REGISTER; +"%nwarpid" TC; ptx_lval.int_value = NWARPID_REG; return SPECIAL_REGISTER; +"%pm"[0-3] TC; sscanf(yytext+3,"%u",&ptx_lval.int_value); ptx_lval.int_value<<=16; ptx_lval.int_value += PM_REG; return SPECIAL_REGISTER; +"%smid" TC; ptx_lval.int_value = SMID_REG; return SPECIAL_REGISTER; +"%tid" TC; ptx_lval.int_value = TID_REG; return SPECIAL_REGISTER; +"%warpid" TC; ptx_lval.int_value = WARPID_REG; return SPECIAL_REGISTER; +"WARP_SZ" TC; ptx_lval.int_value = WARPSZ_REG; return SPECIAL_REGISTER; + +[a-zA-Z_][a-zA-Z0-9_$]* TC; ptx_lval.string_value = strdup(yytext); return IDENTIFIER; +[$%][a-zA-Z0-9_$]+ TC; ptx_lval.string_value = strdup(yytext); return IDENTIFIER; + +[0-9]+\.[0-9]+ TC; sscanf(yytext,"%lf", &ptx_lval.double_value); return DOUBLE_OPERAND; + +0[xX][0-9a-fA-F]+U? TC; CHECK_UNSIGNED; sscanf(yytext,"%x", &ptx_lval.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; +[-]?[0-9]+U? TC; CHECK_UNSIGNED; ptx_lval.int_value = atoi(yytext); return INT_OPERAND; + +0[fF][0-9a-fA-F]{8} TC; sscanf(yytext+2,"%x", (unsigned*)(void*)&ptx_lval.float_value); return FLOAT_OPERAND; +0[dD][0-9a-fA-F]{16} TC; sscanf(yytext+2,"%Lx", (unsigned long long*)(void*)&ptx_lval.double_value); return DOUBLE_OPERAND; + +\.s8 TC; return S8_TYPE; +\.s16 TC; return S16_TYPE; +\.s32 TC; return S32_TYPE; +\.s64 TC; return S64_TYPE; +\.u8 TC; return U8_TYPE; +\.u16 TC; return U16_TYPE; +\.u32 TC; return U32_TYPE; +\.u64 TC; return U64_TYPE; +\.f16 TC; return F16_TYPE; +\.f16x2 TC; return F16_TYPE; /* TODO: figure out what this should really be */ +\.f32 TC; return F32_TYPE; +\.f64 TC; return F64_TYPE; +\.ff64 TC; return FF64_TYPE; +\.b8 TC; return B8_TYPE; +\.b16 TC; return B16_TYPE; +\.b32 TC; return B32_TYPE; +\.b64 TC; return B64_TYPE; +\.bb64 TC; return BB64_TYPE; +\.bb128 TC; return BB128_TYPE; +\.pred TC; return PRED_TYPE; + +\.texref TC; BEGIN(NOT_OPCODE); return TEXREF_TYPE; +\.samplerref TC; return SAMPLERREF_TYPE; +\.surfref TC; return SURFREF_TYPE; + +\.v2 TC; return V2_TYPE; +\.v3 TC; return V3_TYPE; +\.v4 TC; return V4_TYPE; + +\.half TC; return HALF_OPTION; /* ptxplus */ +\.cc TC; return EXTP_OPTION; /* extended precision option */ + +\.equ TC; return EQU_OPTION; +\.neu TC; return NEU_OPTION; +\.ltu TC; return LTU_OPTION; +\.leu TC; return LEU_OPTION; +\.gtu TC; return GTU_OPTION; +\.geu TC; return GEU_OPTION; +\.num TC; return NUM_OPTION; +\.nan TC; return NAN_OPTION; + +\.sat TC; return SAT_OPTION; + +\.eq TC; return EQ_OPTION; +\.ne TC; return NE_OPTION; +\.lt TC; return LT_OPTION; +\.le TC; return LE_OPTION; +\.gt TC; return GT_OPTION; +\.ge TC; return GE_OPTION; +\.cf TC; return CF_OPTION; +\.sf TC; return SF_OPTION; +\.nsf TC; return NSF_OPTION; + +\.lo TC; return LO_OPTION; +\.ls TC; return LS_OPTION; +\.hi TC; return HI_OPTION; +\.hs TC; return HS_OPTION; + + +\.rni TC; return RNI_OPTION; +\.rzi TC; return RZI_OPTION; +\.rmi TC; return RMI_OPTION; +\.rpi TC; return RPI_OPTION; + +\.rn TC; return RN_OPTION; +\.rz TC; return RZ_OPTION; +\.rm TC; return RM_OPTION; +\.rp TC; return RP_OPTION; + +\.ftz TC; return FTZ_OPTION; + +\.neg TC; return NEG_OPTION; + +\.wide TC; return WIDE_OPTION; +\.uni TC; return UNI_OPTION; + +\.sync TC; return SYNC_OPTION; +\.arrive TC; return ARRIVE_OPTION; +\.red TC; return RED_OPTION; + + +\.approx TC; return APPROX_OPTION; +\.full TC; return FULL_OPTION; + +\.any TC; return ANY_OPTION; +\.all TC; return ALL_OPTION; +\.ballot TC; return BALLOT_OPTION; +\.gl TC; return GLOBAL_OPTION; +\.cta TC; return CTA_OPTION; +\.sys TC; return SYS_OPTION; + +\.exit TC; return EXIT_OPTION; + +\.abs TC; return ABS_OPTION; + +\.to TC; return TO_OPTION; + +\.ca TC; return CA_OPTION; +\.cg TC; return CG_OPTION; +\.cs TC; return CS_OPTION; +\.lu TC; return LU_OPTION; +\.cv TC; return CV_OPTION; + +\.wb TC; return WB_OPTION; +\.wt TC; return WT_OPTION; + +\.nc TC; return NC_OPTION; + +\.up TC; return UP_OPTION; +\.down TC; return DOWN_OPTION; +\.bfly TC; return BFLY_OPTION; +\.idx TC; return IDX_OPTION; + +\.popc TC; return ATOMIC_POPC; +\.and TC; return ATOMIC_AND; +\.or TC; return ATOMIC_OR; +\.xor TC; return ATOMIC_XOR; +\.cas TC; return ATOMIC_CAS; +\.exch TC; return ATOMIC_EXCH; +\.add TC; return ATOMIC_ADD; +\.inc TC; return ATOMIC_INC; +\.dec TC; return ATOMIC_DEC; +\.min TC; return ATOMIC_MIN; +\.max TC; return ATOMIC_MAX; + + + +\.1d TC; return GEOM_MODIFIER_1D; +\.2d TC; return GEOM_MODIFIER_2D; +\.3d TC; return GEOM_MODIFIER_3D; + +\.0 TC; ptx_lval.int_value = 0; return DIMENSION_MODIFIER; +\.1 TC; ptx_lval.int_value = 1; return DIMENSION_MODIFIER; +\.2 TC; ptx_lval.int_value = 2; return DIMENSION_MODIFIER; +\.x TC; ptx_lval.int_value = 0; return DIMENSION_MODIFIER; +\.y TC; ptx_lval.int_value = 1; return DIMENSION_MODIFIER; +\.z TC; ptx_lval.int_value = 2; return DIMENSION_MODIFIER; + +"-" TC; return MINUS; +"+" TC; return PLUS; +"," TC; return COMMA; +"@" TC; return PRED; +"|" TC; return PIPE; +"[" TC; return LEFT_SQUARE_BRACKET; +"]" TC; return RIGHT_SQUARE_BRACKET; +"<" TC; return LEFT_ANGLE_BRACKET; +">" TC; return RIGHT_ANGLE_BRACKET; +"(" TC; return LEFT_PAREN; +")" TC; return RIGHT_PAREN; +":" TC; BEGIN(INITIAL); return COLON; +";" TC; BEGIN(INITIAL); return SEMI_COLON; +"!" TC; return EXCLAMATION; +"=" TC; return EQUALS; +"}" TC; return RIGHT_BRACE; +\. TC; return PERIOD; +"/" TC; return BACKSLASH; + +"//"[^\n]* TC; // eat single + +\n.* col=0; strncpy(linebuf, yytext + 1, LINEBUF_SIZE); yyless( 1 ); + +" " TC; +"\t" TC; + + +} + +<IN_FUNC_DECL>"{" TC; BEGIN(INITIAL); return LEFT_BRACE; // starting a statement block (allow next token to be parsed as an opcode) +<INITIAL,NOT_OPCODE>"{" TC; return LEFT_BRACE; // starting a vector operand (next token cannot be opcode) + +<INITIAL>{ +"/*" BEGIN(IN_COMMENT); +} +<IN_COMMENT>{ +"*/" BEGIN(INITIAL); +"CPTX_BEGIN" printf("BEGINNING CUSTOM PTX.\n"); BEGIN(INITIAL); +[^C*\n]+ // eat comment in chunks +"C" // eat the lone C +"*" // eat the lone star +\n TC; +} + +<INITIAL>{ +"\"" BEGIN(IN_STRING); +} +<IN_STRING>{ +"\"" TC; BEGIN(INITIAL); return STRING; +[^\"]* TC; ptx_lval.string_value = strdup(yytext); +} + +<*>\t@@DWARF.*\n + +<INITIAL,NOT_OPCODE,IN_FUNC_DECL>. TC; ptx_error((const char*)NULL); +%% + +extern int g_error_detected; +extern const char *g_filename; + +int ptx_error( const char *s ) +{ + int i; + g_error_detected = 1; + fflush(stdout); + if( s != NULL ) + printf("%s:%u: Syntax error:\n\n", g_filename, ptx_lineno ); + printf(" %s\n", linebuf ); + printf(" "); + for( i=0; i < col-1; i++ ) { + if( linebuf[i] == '\t' ) printf("\t"); + else printf(" "); + } + + printf("^\n\n"); + fflush(stdout); + //exit(1); + return 0; +} diff --git a/cuobjdump_to_ptxplus/ptx.y b/cuobjdump_to_ptxplus/ptx.y new file mode 100644 index 0000000..45392fb --- /dev/null +++ b/cuobjdump_to_ptxplus/ptx.y @@ -0,0 +1,629 @@ +/* +Copyright (c) 2009-2011, Tor M. Aamodt +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 +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. +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 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +%union { + double double_value; + float float_value; + int int_value; + char * string_value; + void * ptr_value; +} + +%token <string_value> STRING +%token <int_value> OPCODE +%token <int_value> WMMA_DIRECTIVE +%token <int_value> LAYOUT +%token <int_value> CONFIGURATION +%token ALIGN_DIRECTIVE +%token BRANCHTARGETS_DIRECTIVE +%token BYTE_DIRECTIVE +%token CALLPROTOTYPE_DIRECTIVE +%token CALLTARGETS_DIRECTIVE +%token <int_value> CONST_DIRECTIVE +%token CONSTPTR_DIRECTIVE +%token PTR_DIRECTIVE +%token ENTRY_DIRECTIVE +%token EXTERN_DIRECTIVE +%token FILE_DIRECTIVE +%token FUNC_DIRECTIVE +%token GLOBAL_DIRECTIVE +%token LOCAL_DIRECTIVE +%token LOC_DIRECTIVE +%token MAXNCTAPERSM_DIRECTIVE +%token MAXNNREG_DIRECTIVE +%token MAXNTID_DIRECTIVE +%token MINNCTAPERSM_DIRECTIVE +%token PARAM_DIRECTIVE +%token PRAGMA_DIRECTIVE +%token REG_DIRECTIVE +%token REQNTID_DIRECTIVE +%token SECTION_DIRECTIVE +%token SHARED_DIRECTIVE +%token SREG_DIRECTIVE +%token SSTARR_DIRECTIVE +%token STRUCT_DIRECTIVE +%token SURF_DIRECTIVE +%token TARGET_DIRECTIVE +%token TEX_DIRECTIVE +%token UNION_DIRECTIVE +%token VERSION_DIRECTIVE +%token ADDRESS_SIZE_DIRECTIVE +%token VISIBLE_DIRECTIVE +%token WEAK_DIRECTIVE +%token <string_value> IDENTIFIER +%token <int_value> INT_OPERAND +%token <float_value> FLOAT_OPERAND +%token <double_value> DOUBLE_OPERAND +%token S8_TYPE +%token S16_TYPE +%token S32_TYPE +%token S64_TYPE +%token U8_TYPE +%token U16_TYPE +%token U32_TYPE +%token U64_TYPE +%token F16_TYPE +%token F32_TYPE +%token F64_TYPE +%token FF64_TYPE +%token B8_TYPE +%token B16_TYPE +%token B32_TYPE +%token B64_TYPE +%token BB64_TYPE +%token BB128_TYPE +%token PRED_TYPE +%token TEXREF_TYPE +%token SAMPLERREF_TYPE +%token SURFREF_TYPE +%token V2_TYPE +%token V3_TYPE +%token V4_TYPE +%token COMMA +%token PRED +%token HALF_OPTION +%token EXTP_OPTION +%token EQ_OPTION +%token NE_OPTION +%token LT_OPTION +%token LE_OPTION +%token GT_OPTION +%token GE_OPTION +%token LO_OPTION +%token LS_OPTION +%token HI_OPTION +%token HS_OPTION +%token EQU_OPTION +%token NEU_OPTION +%token LTU_OPTION +%token LEU_OPTION +%token GTU_OPTION +%token GEU_OPTION +%token NUM_OPTION +%token NAN_OPTION +%token CF_OPTION +%token SF_OPTION +%token NSF_OPTION +%token LEFT_SQUARE_BRACKET +%token RIGHT_SQUARE_BRACKET +%token WIDE_OPTION +%token <int_value> SPECIAL_REGISTER +%token MINUS +%token PLUS +%token COLON +%token SEMI_COLON +%token EXCLAMATION +%token PIPE +%token RIGHT_BRACE +%token LEFT_BRACE +%token EQUALS +%token PERIOD +%token BACKSLASH +%token <int_value> DIMENSION_MODIFIER +%token RN_OPTION +%token RZ_OPTION +%token RM_OPTION +%token RP_OPTION +%token RNI_OPTION +%token RZI_OPTION +%token RMI_OPTION +%token RPI_OPTION +%token UNI_OPTION +%token GEOM_MODIFIER_1D +%token GEOM_MODIFIER_2D +%token GEOM_MODIFIER_3D +%token SAT_OPTION +%token FTZ_OPTION +%token NEG_OPTION +%token SYNC_OPTION +%token RED_OPTION +%token ARRIVE_OPTION +%token ATOMIC_POPC +%token ATOMIC_AND +%token ATOMIC_OR +%token ATOMIC_XOR +%token ATOMIC_CAS +%token ATOMIC_EXCH +%token ATOMIC_ADD +%token ATOMIC_INC +%token ATOMIC_DEC +%token ATOMIC_MIN +%token ATOMIC_MAX +%token LEFT_ANGLE_BRACKET +%token RIGHT_ANGLE_BRACKET +%token LEFT_PAREN +%token RIGHT_PAREN +%token APPROX_OPTION +%token FULL_OPTION +%token ANY_OPTION +%token ALL_OPTION +%token BALLOT_OPTION +%token GLOBAL_OPTION +%token CTA_OPTION +%token SYS_OPTION +%token EXIT_OPTION +%token ABS_OPTION +%token TO_OPTION +%token CA_OPTION; +%token CG_OPTION; +%token CS_OPTION; +%token LU_OPTION; +%token CV_OPTION; +%token WB_OPTION; +%token WT_OPTION; +%token NC_OPTION; +%token UP_OPTION; +%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 + +%{ + #include "ptx_parser.h" + #include <stdlib.h> + #include <string.h> + #include <math.h> + void syntax_not_implemented(); + extern int g_func_decl; + int ptx_lex(void); + int ptx_error(const char *); +%} + +%% + +input: /* empty */ + | input directive_statement + | input function_defn + | input function_decl + ; + +function_defn: function_decl { set_symtab($1); func_header(".skip"); } statement_block { end_function(); } + | function_decl { set_symtab($1); } block_spec_list { func_header(".skip"); } statement_block { end_function(); } + ; + +block_spec: MAXNTID_DIRECTIVE INT_OPERAND COMMA INT_OPERAND COMMA INT_OPERAND {func_header_info_int(".maxntid", $2); + func_header_info_int(",", $4); + func_header_info_int(",", $6); + maxnt_id($2, $4, $6);} + | MINNCTAPERSM_DIRECTIVE INT_OPERAND { func_header_info_int(".minnctapersm", $2); printf("GPGPU-Sim: Warning: .minnctapersm ignored. \n"); } + | MAXNCTAPERSM_DIRECTIVE INT_OPERAND { func_header_info_int(".maxnctapersm", $2); printf("GPGPU-Sim: Warning: .maxnctapersm ignored. \n"); } + ; + +block_spec_list: block_spec + | block_spec_list block_spec + ; + +function_decl: function_decl_header LEFT_PAREN { start_function($1); func_header_info("(");} param_entry RIGHT_PAREN {func_header_info(")");} function_ident_param { $$ = reset_symtab(); } + | function_decl_header { start_function($1); } function_ident_param { $$ = reset_symtab(); } + | function_decl_header { start_function($1); add_function_name(""); g_func_decl=0; $$ = reset_symtab(); } + ; + +function_ident_param: IDENTIFIER { add_function_name($1); } LEFT_PAREN {func_header_info("(");} param_list RIGHT_PAREN { g_func_decl=0; func_header_info(")"); } + | IDENTIFIER { add_function_name($1); g_func_decl=0; } + ; + +function_decl_header: ENTRY_DIRECTIVE { $$ = 1; g_func_decl=1; func_header(".entry"); } + | VISIBLE_DIRECTIVE ENTRY_DIRECTIVE { $$ = 1; g_func_decl=1; func_header(".entry"); } + | WEAK_DIRECTIVE ENTRY_DIRECTIVE { $$ = 1; g_func_decl=1; func_header(".entry"); } + | FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } + | VISIBLE_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } + | WEAK_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } + | EXTERN_DIRECTIVE FUNC_DIRECTIVE { $$ = 2; g_func_decl=1; func_header(".func"); } + | WEAK_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } + ; + +param_list: /*empty*/ + | param_entry { add_directive(); } + | param_list COMMA {func_header_info(",");} param_entry { add_directive(); } + +param_entry: PARAM_DIRECTIVE { add_space_spec(param_space_unclassified,0); } variable_spec ptr_spec identifier_spec { add_function_arg(); } + | REG_DIRECTIVE { add_space_spec(reg_space,0); } variable_spec identifier_spec { add_function_arg(); } + +ptr_spec: /*empty*/ + | PTR_DIRECTIVE ptr_space_spec ptr_align_spec + | PTR_DIRECTIVE ptr_align_spec + +ptr_space_spec: GLOBAL_DIRECTIVE { add_ptr_spec(global_space); } + | LOCAL_DIRECTIVE { add_ptr_spec(local_space); } + | SHARED_DIRECTIVE { add_ptr_spec(shared_space); } + | CONST_DIRECTIVE { add_ptr_spec(global_space); } + +ptr_align_spec: ALIGN_DIRECTIVE INT_OPERAND + +statement_block: LEFT_BRACE statement_list RIGHT_BRACE + +statement_list: directive_statement { add_directive(); } + | instruction_statement { add_instruction(); } + | statement_list directive_statement { add_directive(); } + | statement_list instruction_statement { add_instruction(); } + | statement_list {start_inst_group();} statement_block {end_inst_group();} + | {start_inst_group();} statement_block {end_inst_group();} + ; + +directive_statement: variable_declaration SEMI_COLON + | VERSION_DIRECTIVE DOUBLE_OPERAND { add_version_info($2, 0); } + | VERSION_DIRECTIVE DOUBLE_OPERAND PLUS { add_version_info($2,1); } + | ADDRESS_SIZE_DIRECTIVE INT_OPERAND {/*Do nothing*/} + | TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER { target_header2($2,$4); } + | TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER { target_header3($2,$4,$6); } + | TARGET_DIRECTIVE IDENTIFIER { target_header($2); } + | FILE_DIRECTIVE INT_OPERAND STRING { add_file($2,$3); } + | FILE_DIRECTIVE INT_OPERAND STRING COMMA INT_OPERAND COMMA INT_OPERAND { add_file($2,$3); } + | LOC_DIRECTIVE INT_OPERAND INT_OPERAND INT_OPERAND + | PRAGMA_DIRECTIVE STRING SEMI_COLON { add_pragma($2); } + | function_decl SEMI_COLON {/*Do nothing*/} + ; + +variable_declaration: variable_spec identifier_list { add_variables(); } + | variable_spec identifier_spec EQUALS initializer_list { add_variables(); } + | variable_spec identifier_spec EQUALS literal_operand { add_variables(); } + | CONSTPTR_DIRECTIVE IDENTIFIER COMMA IDENTIFIER COMMA INT_OPERAND { add_constptr($2, $4, $6); } + ; + +variable_spec: var_spec_list { set_variable_type(); } + +identifier_list: identifier_spec + | identifier_list COMMA identifier_spec; + +identifier_spec: IDENTIFIER { add_identifier($1,0,NON_ARRAY_IDENTIFIER); func_header_info($1);} + | IDENTIFIER LEFT_ANGLE_BRACKET INT_OPERAND RIGHT_ANGLE_BRACKET { func_header_info($1); func_header_info_int("<", $3); func_header_info(">"); + int i,lbase,l; + char *id = NULL; + lbase = strlen($1); + for( i=0; i < $3; i++ ) { + l = lbase + (int)log10(i+1)+10; + id = (char*) malloc(l); + snprintf(id,l,"%s%u",$1,i); + add_identifier(id,0,NON_ARRAY_IDENTIFIER); + } + free($1); + } + | IDENTIFIER LEFT_SQUARE_BRACKET RIGHT_SQUARE_BRACKET { add_identifier($1,0,ARRAY_IDENTIFIER_NO_DIM); func_header_info($1); func_header_info("["); func_header_info("]");} + | IDENTIFIER LEFT_SQUARE_BRACKET INT_OPERAND RIGHT_SQUARE_BRACKET { add_identifier($1,$3,ARRAY_IDENTIFIER); func_header_info($1); func_header_info_int("[",$3); func_header_info("]");} + ; + +var_spec_list: var_spec + | var_spec_list var_spec; + +var_spec: space_spec + | type_spec + | align_spec + | VISIBLE_DIRECTIVE + | EXTERN_DIRECTIVE { add_extern_spec(); } + | WEAK_DIRECTIVE + ; + +align_spec: ALIGN_DIRECTIVE INT_OPERAND { add_alignment_spec($2); } + +space_spec: REG_DIRECTIVE { add_space_spec(reg_space,0); } + | SREG_DIRECTIVE { add_space_spec(reg_space,0); } + | addressable_spec + ; + +addressable_spec: CONST_DIRECTIVE { add_space_spec(const_space,$1); } + | GLOBAL_DIRECTIVE { add_space_spec(global_space,0); } + | LOCAL_DIRECTIVE { add_space_spec(local_space,0); } + | PARAM_DIRECTIVE { add_space_spec(param_space_unclassified,0); } + | SHARED_DIRECTIVE { add_space_spec(shared_space,0); } + | SSTARR_DIRECTIVE { add_space_spec(sstarr_space,0); } + | SURF_DIRECTIVE { add_space_spec(surf_space,0); } + | TEX_DIRECTIVE { add_space_spec(tex_space,0); } + ; + +type_spec: scalar_type + | vector_spec scalar_type + ; + +vector_spec: V2_TYPE { add_option(V2_TYPE); func_header_info(".v2");} + | V3_TYPE { add_option(V3_TYPE); func_header_info(".v3");} + | V4_TYPE { add_option(V4_TYPE); func_header_info(".v4");} + ; + +scalar_type: S8_TYPE { add_scalar_type_spec( S8_TYPE ); } + | S16_TYPE { add_scalar_type_spec( S16_TYPE ); } + | S32_TYPE { add_scalar_type_spec( S32_TYPE ); } + | S64_TYPE { add_scalar_type_spec( S64_TYPE ); } + | U8_TYPE { add_scalar_type_spec( U8_TYPE ); } + | U16_TYPE { add_scalar_type_spec( U16_TYPE ); } + | U32_TYPE { add_scalar_type_spec( U32_TYPE ); } + | U64_TYPE { add_scalar_type_spec( U64_TYPE ); } + | F16_TYPE { add_scalar_type_spec( F16_TYPE ); } + | F32_TYPE { add_scalar_type_spec( F32_TYPE ); } + | F64_TYPE { add_scalar_type_spec( F64_TYPE ); } + | FF64_TYPE { add_scalar_type_spec( FF64_TYPE ); } + | B8_TYPE { add_scalar_type_spec( B8_TYPE ); } + | B16_TYPE { add_scalar_type_spec( B16_TYPE ); } + | B32_TYPE { add_scalar_type_spec( B32_TYPE ); } + | B64_TYPE { add_scalar_type_spec( B64_TYPE ); } + | BB64_TYPE { add_scalar_type_spec( BB64_TYPE ); } + | BB128_TYPE { add_scalar_type_spec( BB128_TYPE ); } + | PRED_TYPE { add_scalar_type_spec( PRED_TYPE ); } + | TEXREF_TYPE { add_scalar_type_spec( TEXREF_TYPE ); } + | SAMPLERREF_TYPE { add_scalar_type_spec( SAMPLERREF_TYPE ); } + | SURFREF_TYPE { add_scalar_type_spec( SURFREF_TYPE ); } + ; + +initializer_list: LEFT_BRACE literal_list RIGHT_BRACE { add_array_initializer(); } + | LEFT_BRACE initializer_list RIGHT_BRACE { syntax_not_implemented(); } + +literal_list: literal_operand + | literal_list COMMA literal_operand; + +instruction_statement: instruction SEMI_COLON + | IDENTIFIER COLON { add_label($1); } + | pred_spec instruction SEMI_COLON; + +instruction: opcode_spec LEFT_PAREN operand RIGHT_PAREN { 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 + ; + +opcode_spec: OPCODE { add_opcode($1); } option_list + | OPCODE { add_opcode($1); } + +pred_spec: PRED IDENTIFIER { add_pred($2,0, -1); } + | PRED EXCLAMATION IDENTIFIER { add_pred($3,1, -1); } + | PRED IDENTIFIER LT_OPTION { add_pred($2,0,1); } + | PRED IDENTIFIER EQ_OPTION { add_pred($2,0,2); } + | PRED IDENTIFIER LE_OPTION { add_pred($2,0,3); } + | PRED IDENTIFIER NE_OPTION { add_pred($2,0,5); } + | PRED IDENTIFIER GE_OPTION { add_pred($2,0,6); } + | PRED IDENTIFIER EQU_OPTION { add_pred($2,0,10); } + | PRED IDENTIFIER GTU_OPTION { add_pred($2,0,12); } + | PRED IDENTIFIER NEU_OPTION { add_pred($2,0,13); } + | PRED IDENTIFIER CF_OPTION { add_pred($2,0,17); } + | PRED IDENTIFIER SF_OPTION { add_pred($2,0,19); } + | PRED IDENTIFIER NSF_OPTION { add_pred($2,0,28); } + ; + +option_list: option + | option option_list ; + +option: type_spec + | compare_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); } + | UNI_OPTION { add_option(UNI_OPTION); } + | WIDE_OPTION { add_option(WIDE_OPTION); } + | ANY_OPTION { add_option(ANY_OPTION); } + | ALL_OPTION { add_option(ALL_OPTION); } + | BALLOT_OPTION { add_option(BALLOT_OPTION); } + | GLOBAL_OPTION { add_option(GLOBAL_OPTION); } + | CTA_OPTION { add_option(CTA_OPTION); } + | SYS_OPTION { add_option(SYS_OPTION); } + | GEOM_MODIFIER_1D { add_option(GEOM_MODIFIER_1D); } + | GEOM_MODIFIER_2D { add_option(GEOM_MODIFIER_2D); } + | GEOM_MODIFIER_3D { add_option(GEOM_MODIFIER_3D); } + | SAT_OPTION { add_option(SAT_OPTION); } + | FTZ_OPTION { add_option(FTZ_OPTION); } + | NEG_OPTION { add_option(NEG_OPTION); } + | APPROX_OPTION { add_option(APPROX_OPTION); } + | FULL_OPTION { add_option(FULL_OPTION); } + | EXIT_OPTION { add_option(EXIT_OPTION); } + | ABS_OPTION { add_option(ABS_OPTION); } + | atomic_operation_spec ; + | TO_OPTION { add_option(TO_OPTION); } + | HALF_OPTION { add_option(HALF_OPTION); } + | EXTP_OPTION { add_option(EXTP_OPTION); } + | CA_OPTION { add_option(CA_OPTION); } + | CG_OPTION { add_option(CG_OPTION); } + | CS_OPTION { add_option(CS_OPTION); } + | LU_OPTION { add_option(LU_OPTION); } + | CV_OPTION { add_option(CV_OPTION); } + | WB_OPTION { add_option(WB_OPTION); } + | WT_OPTION { add_option(WT_OPTION); } + | NC_OPTION { add_option(NC_OPTION); } + | UP_OPTION { add_option(UP_OPTION); } + | DOWN_OPTION { add_option(DOWN_OPTION); } + | BFLY_OPTION { add_option(BFLY_OPTION); } + | IDX_OPTION { add_option(IDX_OPTION); } + ; + +atomic_operation_spec: ATOMIC_AND { add_option(ATOMIC_AND); } + | ATOMIC_POPC { add_option(ATOMIC_POPC); } + | ATOMIC_OR { add_option(ATOMIC_OR); } + | ATOMIC_XOR { add_option(ATOMIC_XOR); } + | ATOMIC_CAS { add_option(ATOMIC_CAS); } + | ATOMIC_EXCH { add_option(ATOMIC_EXCH); } + | ATOMIC_ADD { add_option(ATOMIC_ADD); } + | ATOMIC_INC { add_option(ATOMIC_INC); } + | ATOMIC_DEC { add_option(ATOMIC_DEC); } + | ATOMIC_MIN { add_option(ATOMIC_MIN); } + | ATOMIC_MAX { add_option(ATOMIC_MAX); } + ; + +rounding_mode: floating_point_rounding_mode + | integer_rounding_mode; + + +floating_point_rounding_mode: RN_OPTION { add_option(RN_OPTION); } + | RZ_OPTION { add_option(RZ_OPTION); } + | RM_OPTION { add_option(RM_OPTION); } + | RP_OPTION { add_option(RP_OPTION); } + ; + +integer_rounding_mode: RNI_OPTION { add_option(RNI_OPTION); } + | RZI_OPTION { add_option(RZI_OPTION); } + | RMI_OPTION { add_option(RMI_OPTION); } + | RPI_OPTION { add_option(RPI_OPTION); } + ; + +compare_spec:EQ_OPTION { add_option(EQ_OPTION); } + | NE_OPTION { add_option(NE_OPTION); } + | LT_OPTION { add_option(LT_OPTION); } + | LE_OPTION { add_option(LE_OPTION); } + | GT_OPTION { add_option(GT_OPTION); } + | GE_OPTION { add_option(GE_OPTION); } + | LO_OPTION { add_option(LO_OPTION); } + | LS_OPTION { add_option(LS_OPTION); } + | HI_OPTION { add_option(HI_OPTION); } + | HS_OPTION { add_option(HS_OPTION); } + | EQU_OPTION { add_option(EQU_OPTION); } + | NEU_OPTION { add_option(NEU_OPTION); } + | LTU_OPTION { add_option(LTU_OPTION); } + | LEU_OPTION { add_option(LEU_OPTION); } + | GTU_OPTION { add_option(GTU_OPTION); } + | GEU_OPTION { add_option(GEU_OPTION); } + | NUM_OPTION { add_option(NUM_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);} + ; + +vp_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);} + ; + + + +operand_list: operand + | operand COMMA operand_list; + +operand: IDENTIFIER { add_scalar_operand( $1 ); } + | EXCLAMATION IDENTIFIER { add_neg_pred_operand( $2 ); } + | MINUS IDENTIFIER { add_scalar_operand( $2 ); change_operand_neg(); } + | memory_operand + | literal_operand + | builtin_operand + | vector_operand + | MINUS vector_operand { change_operand_neg(); } + | tex_operand + | IDENTIFIER PLUS INT_OPERAND { add_address_operand($1,$3); } + | IDENTIFIER LO_OPTION { add_scalar_operand( $1 ); change_operand_lohi(1);} + | MINUS IDENTIFIER LO_OPTION { add_scalar_operand( $2 ); change_operand_lohi(1); change_operand_neg();} + | IDENTIFIER HI_OPTION { add_scalar_operand( $1 ); change_operand_lohi(2);} + | MINUS IDENTIFIER HI_OPTION { add_scalar_operand( $2 ); change_operand_lohi(2); change_operand_neg();} + | IDENTIFIER PIPE IDENTIFIER { add_2vector_operand($1,$3); change_double_operand_type(-1);} + | IDENTIFIER PIPE IDENTIFIER LO_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-1); change_operand_lohi(1);} + | IDENTIFIER PIPE IDENTIFIER HI_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-1); change_operand_lohi(2);} + | IDENTIFIER BACKSLASH IDENTIFIER { add_2vector_operand($1,$3); change_double_operand_type(-3);} + | IDENTIFIER BACKSLASH IDENTIFIER LO_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-3); change_operand_lohi(1);} + | IDENTIFIER BACKSLASH IDENTIFIER HI_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-3); change_operand_lohi(2);} + ; + +vector_operand: LEFT_BRACE IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_2vector_operand($2,$4); } + | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_3vector_operand($2,$4,$6); } + | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_4vector_operand($2,$4,$6,$8); } + | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_8vector_operand($2,$4,$6,$8,$10,$12,$14,$16); } + | LEFT_BRACE IDENTIFIER RIGHT_BRACE { add_1vector_operand($2); } + ; + +tex_operand: LEFT_SQUARE_BRACKET IDENTIFIER COMMA { add_scalar_operand($2); } + vector_operand + RIGHT_SQUARE_BRACKET + ; + +builtin_operand: SPECIAL_REGISTER DIMENSION_MODIFIER { add_builtin_operand($1,$2); } + | SPECIAL_REGISTER { add_builtin_operand($1,-1); } + ; + +memory_operand : LEFT_SQUARE_BRACKET address_expression RIGHT_SQUARE_BRACKET { add_memory_operand(); } + | IDENTIFIER LEFT_SQUARE_BRACKET address_expression RIGHT_SQUARE_BRACKET { add_memory_operand(); change_memory_addr_space($1); } + | IDENTIFIER LEFT_SQUARE_BRACKET literal_operand RIGHT_SQUARE_BRACKET { change_memory_addr_space($1); } + | IDENTIFIER LEFT_SQUARE_BRACKET twin_operand RIGHT_SQUARE_BRACKET { change_memory_addr_space($1); add_memory_operand();} + | MINUS memory_operand { change_operand_neg(); } + ; + +twin_operand : IDENTIFIER PLUS IDENTIFIER { add_double_operand($1,$3); change_double_operand_type(1); } + | IDENTIFIER PLUS IDENTIFIER LO_OPTION { add_double_operand($1,$3); change_double_operand_type(1); change_operand_lohi(1); } + | IDENTIFIER PLUS IDENTIFIER HI_OPTION { add_double_operand($1,$3); change_double_operand_type(1); change_operand_lohi(2); } + | IDENTIFIER PLUS EQUALS IDENTIFIER { add_double_operand($1,$4); change_double_operand_type(2); } + | IDENTIFIER PLUS EQUALS IDENTIFIER LO_OPTION { add_double_operand($1,$4); change_double_operand_type(2); change_operand_lohi(1); } + | IDENTIFIER PLUS EQUALS IDENTIFIER HI_OPTION { add_double_operand($1,$4); change_double_operand_type(2); change_operand_lohi(2); } + | IDENTIFIER PLUS EQUALS INT_OPERAND { add_address_operand($1,$4); change_double_operand_type(3); } + ; + +literal_operand : INT_OPERAND { add_literal_int($1); } + | FLOAT_OPERAND { add_literal_float($1); } + | DOUBLE_OPERAND { add_literal_double($1); } + ; + +address_expression: IDENTIFIER { add_address_operand($1,0); } + | IDENTIFIER LO_OPTION { add_address_operand($1,0); change_operand_lohi(1);} + | IDENTIFIER HI_OPTION { add_address_operand($1,0); change_operand_lohi(2); } + | IDENTIFIER PLUS INT_OPERAND { add_address_operand($1,$3); } + | INT_OPERAND { add_address_operand2($1); } + ; + +%% + +extern int ptx_lineno; +extern const char *g_filename; + +void syntax_not_implemented() +{ + printf("Parse error (%s:%u): this syntax is not (yet) implemented:\n",g_filename,ptx_lineno); + ptx_error(NULL); + abort(); +} diff --git a/diff.diff b/diff.diff deleted file mode 100644 index 8ab27fe..0000000 --- a/diff.diff +++ /dev/null @@ -1,173 +0,0 @@ -diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc -index 5964a4d..53436d3 100644 ---- a/libcuda/cuda_runtime_api.cc -+++ b/libcuda/cuda_runtime_api.cc -@@ -182,6 +182,8 @@ cudaError_t g_last_cudaError = cudaSuccess; - - extern stream_manager *g_stream_manager; - -+ -+ - void register_ptx_function( const char *name, function_info *impl ) - { - // no longer need this -@@ -1341,6 +1343,29 @@ std::string get_app_binary(){ - return self_exe_path; - } - -+static int get_app_cuda_version() { -+ int app_cuda_version = 0; -+ char fname[1024]; -+ snprintf(fname,1024,"_app_cuda_version_XXXXXX"); -+ int fd=mkstemp(fname); -+ close(fd); -+ std::string app_cuda_version_command = "ldd " + get_app_binary() + " | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " + fname; -+ system(app_cuda_version_command.c_str()); -+ FILE * cmd = fopen(fname, "r"); -+ char buf[256]; -+ while (fgets(buf, sizeof(buf), cmd) != 0) { -+ std::cout << buf; -+ app_cuda_version = atoi(buf); -+ } -+ fclose(cmd); -+ if ( app_cuda_version == 0 ) { -+ printf( "Error - Cannot detect the app's CUDA version.\n" ); -+ exit(1); -+ } -+ return app_cuda_version; -+} -+ -+ - //! Call cuobjdump to extract everything (-elf -sass -ptx) - /*! - * This Function extract the whole PTX (for all the files) using cuobjdump -@@ -1366,23 +1391,10 @@ void extract_code_using_cuobjdump(){ - // Running cuobjdump using dynamic link to current process - // Needs the option '-all' to extract PTX from CDP-enabled binary - extern bool g_cdp_enabled; -- const int current_cuda = atoi(getenv("CUDA_VERSION_NUMBER")); -- if ( context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() && current_cuda > 4020 ) { -- const char* cuda_42_path = getenv("CUDA_42_INSTALL_PATH"); -- if ( NULL == cuda_42_path ) { -- printf("You are using a new version of CUDA and PTXPLUS. You are required to have CUDA SDK 4.2 and explicitly " -- "point to it via the environment variable $CUDA_42_INSTALL_PATH.\n\n"); -- exit(1); -- } else { -- command = "$CUDA_42_INSTALL_PATH/bin/cuobjdump"; -- } -- } else { -- command = "$CUDA_42_INSTALL_PATH/bin/cuobjdump"; -- } - if(!g_cdp_enabled) -- command += " -ptx -elf -sass " + app_binary + " > " + fname; -+ command = "$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass " + app_binary + " > " + fname; - else -- command += " -ptx -elf -sass -all " + app_binary + " > " + fname; -+ command = "$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass -all " + app_binary + " > " + fname; - bool parse_output = true; - int result = system(command.c_str()); - if(result) { -@@ -1765,6 +1777,7 @@ void cuobjdumpParseBinary(unsigned int handle){ - //TODO: Remove temporarily files as per configurations - } - -+ - void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin ) - { - #if (CUDART_VERSION < 2010) -@@ -1783,26 +1796,10 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin ) - // Making this a runtime variable based on the app, enables GPGPU-Sim compiled - // with a newer version of CUDA to run apps compiled with older versions of - // CUDA. This is especially useful for PTXPLUS execution. -- char fname[1024]; -- snprintf(fname,1024,"_app_cuda_version_XXXXXX"); -- int fd=mkstemp(fname); -- close(fd); -- int app_cuda_version = 0; -- std::string app_cuda_version_command = "ldd " + get_app_binary() + " | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " + fname; -- system(app_cuda_version_command.c_str()); -- FILE * cmd = fopen(fname, "r"); -- char buf[256]; -- while (fgets(buf, sizeof(buf), cmd) != 0) { -- std::cout << buf; -- app_cuda_version = atoi(buf); -- } -- fclose(cmd); -- if ( app_cuda_version == 0 ) { -- printf( "Error - Cannot detect the app's CUDA version.\n" ); -- exit(1); -- } -+ int app_cuda_version = get_app_cuda_version(); -+ assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator." ); - const char* filename; -- if ( app_cuda_version < 6 ) { -+#if CUDART_VERSION < 6000 - // FatBin handle from the .fatbin.c file (one of the intermediate files generated by NVCC) - typedef struct {int m; int v; const unsigned long long* d; char* f;} __fatDeviceText __attribute__ ((aligned (8))); - __fatDeviceText * fatDeviceText = (__fatDeviceText *) fatCubin; -@@ -1814,9 +1811,9 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin ) - char * pfatbin = (char*) fatDeviceText->d; - int offset = *((int*)(pfatbin+48)); - filename = (pfatbin+16+offset); -- } else { -+#else - filename = "default"; -- } -+#endif - - // The extracted file name is associated with a fat_cubin_handle passed - // into cudaLaunch(). Inside cudaLaunch(), the associated file name is -diff --git a/setup_environment b/setup_environment -index 8bcb9aa..e5cd4fa 100644 ---- a/setup_environment -+++ b/setup_environment -@@ -134,18 +134,26 @@ else - echo "configured without a power model."; - fi - -+export PTXAS_CUDA_INSTALL_PATH=$CUDA_INSTALL_PATH -+echo ""; -+echo "----------------------------------------------------------------------------"; -+echo "WARNING - If you only care about PTX execution, ignore this warning. GPGPU-Sim supports PTX execution in modern CUDA." - if [ $CUDA_VERSION_NUMBER -gt 4200 ]; then -- echo ""; -- echo "----------------------------------------------------------------------------"; -- echo "WARNING - If you only care about PTX execution, ignore this warning. GPGPU-Sim supports PTX execution in modern CUDA." -- echo "If you want to run PTXPLUS, download SDK 4.2 (in addition to your modern CUDA) and set \$CUDA_42_INSTALL_PATH." -- echo "The following text describes why:"; -- echo "If you are using PTXPLUS, only sm_1x is supported and it requires that the app binaries are compiled in CUDA 4.2 or less."; -- echo "New versions of CUDA tools have dropped parsing support for sm_1x - therefore to use PTXPLUS with a modern card configuration, you must"; -- echo "have both CUDA 4.2 and a modern CUDA installed. When running PTXPLUS under a CUDA version >= 4.2, the simulator will fail unless \$CUDA_42_INSTALL_PATH"; -- echo "has been set properly. You must set this manually."; -- echo "----------------------------------------------------------------------------" -+ echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration, the apps and simulator must be compiled with CUDA 4.2." -+ echo "You can still run a PASCAL configuration when compiling with 4.2 by setting the \$PTXAS_CUDA_INSTALL_PATH directory environment variable." -+else -+ echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration - set the envronment variable" -+ echo "\$PTXAS_CUDA_INSTALL_PATH to point a CUDA version compabible with your card configurations (i.e. 8+ for PASCAL, 9+ for VOLTA etc..)" -+ echo "For example: \"export \$PTXAS_CUDA_INSTALL_PATH=/usr/local/cuda-9.1\"" - fi -+echo "The following text describes why:"; -+echo "If you are using PTXPLUS, only sm_1x is supported and it requires that the app and simulator binaries are compiled in CUDA 4.2 or less."; -+echo "The simulator requires it since CUDA headers desribe struct sizes in the exec which change from gen to gen."; -+echo "The apps require 4.2 because new versions of CUDA tools have dropped parsing support for generating sm_1x"; -+echo "When running using modern config (i.e. pascal) and PTXPLUS with CUDA 4.2, the \$PTXAS_CUDA_INSTALL_PATH env variable is required to get proper register usage" -+echo "(and hence occupancy) using a version of CUDA that knows the register usage on the real card." -+echo ""; -+echo "----------------------------------------------------------------------------"; - - echo "setup_environment succeeded"; - -diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc -index 22f03b9..d8e04d4 100644 ---- a/src/cuda-sim/ptx_loader.cc -+++ b/src/cuda-sim/ptx_loader.cc -@@ -339,7 +339,7 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num - snprintf(extra_flags,1024,"--compile-only --gpu-name=sm_%u",g_occupancy_sm_number); - #endif - -- snprintf(commandline,1024,"$CUDA_INSTALL_PATH/bin/ptxas %s -v %s --output-file /dev/null 2> %s", -+ snprintf(commandline,1024,"$PTXAS_CUDA_INSTALL_PATH/bin/ptxas %s -v %s --output-file /dev/null 2> %s", - extra_flags, fname2, tempfile_ptxinfo); - printf("GPGPU-Sim PTX: generating ptxinfo using \"%s\"\n", commandline); - result = system(commandline); diff --git a/groovy-html.nightly.success.template b/groovy-html.nightly.success.template new file mode 100644 index 0000000..210b924 --- /dev/null +++ b/groovy-html.nightly.success.template @@ -0,0 +1,74 @@ +<STYLE> + BODY, TABLE, TD, TH, P { + font-family: Courier New, Verdana, Helvetica, sans serif; + font-size: 10px; + color: black; + } + .console { + font-family: Courier New; + } + .filesChanged { + width: 10%; + padding-left: 10px; + } + .section { + width: 100%; + border: thin black dotted; + } + .td-title-main { + color: white; + font-size: 200%; + padding-left: 5px; + font-weight: bold; + } + .td-title { + color: white; + font-size: 120%; + font-weight: bold; + padding-left: 5px; + text-transform: uppercase; + } + .td-title-tests { + font-weight: bold; + font-size: 120%; + } + .td-header-maven-module { + font-weight: bold; + font-size: 120%; + } + .td-maven-artifact { + padding-left: 5px; + } + .tr-title { + background-color: <%= (build.result == null || build.result.toString() == 'SUCCESS') ? '#27AE60' : build.result.toString() == 'FAILURE' ? '#E74C3C' : '#f4e242' %>; + } + .test { + padding-left: 20px; + } + .test-fixed { + color: #27AE60; + } + .test-failed { + color: #E74C3C; + } +</STYLE> +<BODY> + +<% + import hudson.model.* + + def JOB_NAME= build.getEnvVars()["JOB_NAME"]; + def BUILD_NUMBER= build.getEnvVars()["BUILD_NUMBER"]; + def BUILD_URL= build.getEnvVars()["BUILD_URL"]; +%> + +See ${BUILD_URL} for full build detials. + +<pre>Statistics changes since last commit: +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/ +<pre> Correlation: +<pre> 9.1: +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/titanv-cycles.cuda-9.1.nightly.html +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/titanv-cycles.cuda-9.1.nightly.apps.txt +<pre> Correlation also posted to: https://engineering.purdue.edu/tgrogers/group/correlator.html +</BODY> diff --git a/groovy-html.success.template b/groovy-html.success.template new file mode 100644 index 0000000..974cc61 --- /dev/null +++ b/groovy-html.success.template @@ -0,0 +1,77 @@ +<STYLE> + BODY, TABLE, TD, TH, P { + font-family: Courier New, Verdana, Helvetica, sans serif; + font-size: 10px; + color: black; + } + .console { + font-family: Courier New; + } + .filesChanged { + width: 10%; + padding-left: 10px; + } + .section { + width: 100%; + border: thin black dotted; + } + .td-title-main { + color: white; + font-size: 200%; + padding-left: 5px; + font-weight: bold; + } + .td-title { + color: white; + font-size: 120%; + font-weight: bold; + padding-left: 5px; + text-transform: uppercase; + } + .td-title-tests { + font-weight: bold; + font-size: 120%; + } + .td-header-maven-module { + font-weight: bold; + font-size: 120%; + } + .td-maven-artifact { + padding-left: 5px; + } + .tr-title { + background-color: <%= (build.result == null || build.result.toString() == 'SUCCESS') ? '#27AE60' : build.result.toString() == 'FAILURE' ? '#E74C3C' : '#f4e242' %>; + } + .test { + padding-left: 20px; + } + .test-fixed { + color: #27AE60; + } + .test-failed { + color: #E74C3C; + } +</STYLE> +<BODY> + +<% + import hudson.model.* + + def JOB_NAME= build.getEnvVars()["JOB_NAME"]; + def BUILD_NUMBER= build.getEnvVars()["BUILD_NUMBER"]; + def BUILD_URL= build.getEnvVars()["BUILD_URL"]; +%> + +See ${BUILD_URL} for full build detials. + +<pre>Statistics changes since last commit: +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/ +<pre> Correlation: +<pre> 4.2: +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/titanv-cycles.cuda-4.2.html +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/titanv-cycles.cuda-4.2.apps.txt +<pre> 10.1: +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/titanv-cycles.cuda-10.1.html +<pre> https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/jenkins/${JOB_NAME}/${BUILD_NUMBER}/titanv-cycles.cuda-10.1.apps.txt +<pre> Correlation also posted to: https://engineering.purdue.edu/tgrogers/group/correlator.html +</BODY> diff --git a/libcuda/Makefile b/libcuda/Makefile index 13932e2..c8ff2e3 100644 --- a/libcuda/Makefile +++ b/libcuda/Makefile @@ -111,10 +111,10 @@ $(OUTPUT_DIR)/%.o: %.cc $(CPP) $(CXXFLAGS) -I./ -I$(OUTPUT_DIR) -I$(CUDA_INSTALL_PATH)/include -c $< -o $@ $(OUTPUT_DIR)/%.o: %.c - $(CC) $(CCFLAGS) -I./ -I$(OUTPUT_DIR) -I$(CUDA_INSTALL_PATH)/include -c $< -o $@ + $(CPP) $(CCFLAGS) -I./ -I$(OUTPUT_DIR) -I$(CUDA_INSTALL_PATH)/include -c $< -o $@ $(OUTPUT_DIR)/%.o: $(OUTPUT_DIR)/%.c - $(CC) $(CCFLAGS) -I./ -I$(OUTPUT_DIR) -I$(CUDA_INSTALL_PATH)/include -c $< -o $@ + $(CPP) $(CCFLAGS) -I./ -I$(OUTPUT_DIR) -I$(CUDA_INSTALL_PATH)/include -c $< -o $@ $(OUTPUT_DIR)/cuobjdump_parser.c: cuobjdump.y $(YACC) $(YFLAGS) -p cuobjdump_ -o$@ $< --file-prefix=$(OUTPUT_DIR)/cuobjdump diff --git a/libcuda/cuda_api_object.h b/libcuda/cuda_api_object.h new file mode 100644 index 0000000..51416f2 --- /dev/null +++ b/libcuda/cuda_api_object.h @@ -0,0 +1,213 @@ +#ifndef __cuda_api_object_h__ +#define __cuda_api_object_h__ + +#include <list> +#include <map> +#include <set> +#include <string> + +#include "builtin_types.h" + +#include "../src/gpgpu-sim/gpu-sim.h" +#include "../src/cuda-sim/ptx_ir.h" +#include "../src/abstract_hardware_model.h" +#include "cuobjdump.h" + +typedef std::list<gpgpu_ptx_sim_arg> gpgpu_ptx_sim_arg_list_t; + +#ifndef OPENGL_SUPPORT +typedef unsigned long GLuint; +#endif + +struct glbmap_entry { + GLuint m_bufferObj; + void *m_devPtr; + size_t m_size; + struct glbmap_entry *m_next; +}; + +typedef struct glbmap_entry glbmap_entry_t; + +struct _cuda_device_id { + _cuda_device_id(gpgpu_sim* gpu) {m_id = 0; m_next = NULL; m_gpgpu=gpu;} + struct _cuda_device_id *next() { return m_next; } + unsigned num_shader() const { return m_gpgpu->get_config().num_shader(); } + int num_devices() const { + if( m_next == NULL ) return 1; + else return 1 + m_next->num_devices(); + } + struct _cuda_device_id *get_device( unsigned n ) + { + assert( n < (unsigned)num_devices() ); + struct _cuda_device_id *p=this; + for(unsigned i=0; i<n; i++) + p = p->m_next; + return p; + } + const struct cudaDeviceProp *get_prop() const + { + return m_gpgpu->get_prop(); + } + unsigned get_id() const { return m_id; } + + gpgpu_sim *get_gpgpu() { return m_gpgpu; } +private: + unsigned m_id; + class gpgpu_sim *m_gpgpu; + struct _cuda_device_id *m_next; +}; + +struct CUctx_st { + CUctx_st( _cuda_device_id *gpu ) + { + m_gpu = gpu; + m_binary_info.cmem = 0; + m_binary_info.gmem = 0; + no_of_ptx=0; + } + + _cuda_device_id *get_device() { return m_gpu; } + + void add_binary( symbol_table *symtab, unsigned fat_cubin_handle ) + { + m_code[fat_cubin_handle] = symtab; + m_last_fat_cubin_handle = fat_cubin_handle; + } + + void add_ptxinfo( const char *deviceFun, const struct gpgpu_ptx_sim_info &info ) + { + symbol *s = m_code[m_last_fat_cubin_handle]->lookup(deviceFun); + assert( s != NULL ); + function_info *f = s->get_pc(); + assert( f != NULL ); + f->set_kernel_info(info); + } + + void add_ptxinfo( const struct gpgpu_ptx_sim_info &info ) + { + m_binary_info = info; + } + + void register_function( unsigned fat_cubin_handle, const char *hostFun, const char *deviceFun ) + { + if( m_code.find(fat_cubin_handle) != m_code.end() ) { + symbol *s = m_code[fat_cubin_handle]->lookup(deviceFun); + if(s != NULL) { + function_info *f = s->get_pc(); + assert( f != NULL ); + m_kernel_lookup[hostFun] = f; + } + else { + printf("Warning: cannot find deviceFun %s\n", deviceFun); + m_kernel_lookup[hostFun] = NULL; + } + // assert( s != NULL ); + // function_info *f = s->get_pc(); + // assert( f != NULL ); + // m_kernel_lookup[hostFun] = f; + } else { + m_kernel_lookup[hostFun] = NULL; + } + } + + void register_hostFun_function( const char*hostFun, function_info* f){ + m_kernel_lookup[hostFun] = f; + } + + function_info *get_kernel(const char *hostFun) + { + std::map<const void*,function_info*>::iterator i=m_kernel_lookup.find(hostFun); + assert( i != m_kernel_lookup.end() ); + return i->second; + } + + int no_of_ptx; + +private: + _cuda_device_id *m_gpu; // selected gpu + std::map<unsigned,symbol_table*> m_code; // fat binary handle => global symbol table + unsigned m_last_fat_cubin_handle; + std::map<const void*,function_info*> m_kernel_lookup; // unique id (CUDA app function address) => kernel entry point + struct gpgpu_ptx_sim_info m_binary_info; + +}; + +class kernel_config { +public: + kernel_config( dim3 GridDim, dim3 BlockDim, size_t sharedMem, struct CUstream_st *stream ) + { + m_GridDim=GridDim; + m_BlockDim=BlockDim; + m_sharedMem=sharedMem; + m_stream = stream; + } + kernel_config() + { + m_GridDim=dim3(-1,-1,-1); + m_BlockDim=dim3(-1,-1,-1); + m_sharedMem=0; + m_stream =NULL; + } + void set_arg( const void *arg, size_t size, size_t offset ) + { + m_args.push_front( gpgpu_ptx_sim_arg(arg,size,offset) ); + } + dim3 grid_dim() const { return m_GridDim; } + dim3 block_dim() const { return m_BlockDim; } + void set_grid_dim(dim3 *d) { m_GridDim = *d; } + void set_block_dim(dim3 *d) { m_BlockDim = *d; } + gpgpu_ptx_sim_arg_list_t get_args() { return m_args; } + struct CUstream_st *get_stream() { return m_stream; } + +private: + dim3 m_GridDim; + dim3 m_BlockDim; + size_t m_sharedMem; + struct CUstream_st *m_stream; + gpgpu_ptx_sim_arg_list_t m_args; +}; + +class cuda_runtime_api { + public: + cuda_runtime_api( gpgpu_context* ctx ) { + g_glbmap = NULL; + g_active_device = 0; //active gpu that runs the code + gpgpu_ctx = ctx; + } + // global list + std::list<cuobjdumpSection*> cuobjdumpSectionList; + std::list<cuobjdumpSection*> libSectionList; + std::list<kernel_config> g_cuda_launch_stack; + std::map<int, bool>fatbin_registered; + std::map<int, std::string> fatbinmap; + std::map<std::string, symbol_table*> name_symtab; + std::map<unsigned long long, size_t> g_mallocPtr_Size; + //maps sm version number to set of filenames + std::map<unsigned, std::set<std::string> > version_filename; + std::map<void *,void **> pinned_memory; //support for pinned memories added + std::map<void *, size_t> pinned_memory_size; + glbmap_entry_t* g_glbmap; + int g_active_device; //active gpu that runs the code + // backward pointer + class gpgpu_context* gpgpu_ctx; + // member function list + void cuobjdumpInit(); + void extract_code_using_cuobjdump(); + void extract_ptx_files_using_cuobjdump(CUctx_st *context); + std::list<cuobjdumpSection*> pruneSectionList(CUctx_st *context); + std::list<cuobjdumpSection*> mergeMatchingSections(std::string identifier); + std::list<cuobjdumpSection*> mergeSections(); + cuobjdumpELFSection* findELFSection(const std::string identifier); + cuobjdumpPTXSection* findPTXSection(const std::string identifier); + cuobjdumpPTXSection* findPTXSectionInList(std::list<cuobjdumpSection*> §ionlist, const std::string identifier); + void cuobjdumpRegisterFatBinary(unsigned int handle, const char* filename, CUctx_st *context); + kernel_info_t *gpgpu_cuda_ptx_sim_init_grid( const char *kernel_key, + gpgpu_ptx_sim_arg_list_t args, + struct dim3 gridDim, + struct dim3 blockDim, + struct CUctx_st* context ); + int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr, gpgpu_t *gpu ); + int load_constants( symbol_table *symtab, addr_t min_gaddr, gpgpu_t *gpu ); + +}; +#endif /* __cuda_api_object_h__ */ diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index 45511d4..9d685e6 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -131,6 +131,8 @@ #if (CUDART_VERSION < 8000) #include "__cudaFatFormat.h" #endif +#include "gpgpu_context.h" +#include "cuda_api_object.h" #include "../src/gpgpu-sim/gpu-sim.h" #include "../src/cuda-sim/ptx_loader.h" #include "../src/cuda-sim/cuda-sim.h" @@ -147,25 +149,10 @@ #include <mach-o/dyld.h> #endif -std::map<void *,void **> pinned_memory; //support for pinned memories added -std::map<void *, size_t> pinned_memory_size; -std::map<unsigned long long, size_t> g_mallocPtr_Size; -int no_of_ptx=0; -//maps sm version number to set of filenames -std::map<unsigned, std::set<std::string> > version_filename; extern void synchronize(); extern void exit_simulation(); -static int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr, gpgpu_t *gpu ); -static int load_constants( symbol_table *symtab, addr_t min_gaddr, gpgpu_t *gpu ); - -static kernel_info_t *gpgpu_cuda_ptx_sim_init_grid( const char *kernel_key, - gpgpu_ptx_sim_arg_list_t args, - struct dim3 gridDim, - struct dim3 blockDim, - struct CUctx_st* context ); - /*DEVICE_BUILTIN*/ struct cudaArray { @@ -189,7 +176,7 @@ struct cudaArray cudaError_t g_last_cudaError = cudaSuccess; -extern stream_manager *g_stream_manager; +//extern stream_manager *g_stream_manager(); void register_ptx_function( const char *name, function_info *impl ) { @@ -210,145 +197,10 @@ void register_ptx_function( const char *name, function_info *impl ) # endif #endif -struct _cuda_device_id { - _cuda_device_id(gpgpu_sim* gpu) {m_id = 0; m_next = NULL; m_gpgpu=gpu;} - struct _cuda_device_id *next() { return m_next; } - unsigned num_shader() const { return m_gpgpu->get_config().num_shader(); } - int num_devices() const { - if( m_next == NULL ) return 1; - else return 1 + m_next->num_devices(); - } - struct _cuda_device_id *get_device( unsigned n ) - { - assert( n < (unsigned)num_devices() ); - struct _cuda_device_id *p=this; - for(unsigned i=0; i<n; i++) - p = p->m_next; - return p; - } - const struct cudaDeviceProp *get_prop() const - { - return m_gpgpu->get_prop(); - } - unsigned get_id() const { return m_id; } - - gpgpu_sim *get_gpgpu() { return m_gpgpu; } -private: - unsigned m_id; - class gpgpu_sim *m_gpgpu; - struct _cuda_device_id *m_next; -}; - -struct CUctx_st { - CUctx_st( _cuda_device_id *gpu ) - { - m_gpu = gpu; - m_binary_info.cmem = 0; - m_binary_info.gmem = 0; - } - - _cuda_device_id *get_device() { return m_gpu; } - - void add_binary( symbol_table *symtab, unsigned fat_cubin_handle ) - { - m_code[fat_cubin_handle] = symtab; - m_last_fat_cubin_handle = fat_cubin_handle; - } - - void add_ptxinfo( const char *deviceFun, const struct gpgpu_ptx_sim_info &info ) - { - symbol *s = m_code[m_last_fat_cubin_handle]->lookup(deviceFun); - assert( s != NULL ); - function_info *f = s->get_pc(); - assert( f != NULL ); - f->set_kernel_info(info); - } - - void add_ptxinfo( const struct gpgpu_ptx_sim_info &info ) - { - m_binary_info = info; - } - - void register_function( unsigned fat_cubin_handle, const char *hostFun, const char *deviceFun ) - { - if( m_code.find(fat_cubin_handle) != m_code.end() ) { - symbol *s = m_code[fat_cubin_handle]->lookup(deviceFun); - if(s != NULL) { - function_info *f = s->get_pc(); - assert( f != NULL ); - m_kernel_lookup[hostFun] = f; - } - else { - printf("Warning: cannot find deviceFun %s\n", deviceFun); - m_kernel_lookup[hostFun] = NULL; - } - // assert( s != NULL ); - // function_info *f = s->get_pc(); - // assert( f != NULL ); - // m_kernel_lookup[hostFun] = f; - } else { - m_kernel_lookup[hostFun] = NULL; - } - } - - void register_hostFun_function( const char*hostFun, function_info* f){ - m_kernel_lookup[hostFun] = f; - } - - function_info *get_kernel(const char *hostFun) - { - std::map<const void*,function_info*>::iterator i=m_kernel_lookup.find(hostFun); - assert( i != m_kernel_lookup.end() ); - return i->second; - } - -private: - _cuda_device_id *m_gpu; // selected gpu - std::map<unsigned,symbol_table*> m_code; // fat binary handle => global symbol table - unsigned m_last_fat_cubin_handle; - std::map<const void*,function_info*> m_kernel_lookup; // unique id (CUDA app function address) => kernel entry point - struct gpgpu_ptx_sim_info m_binary_info; - -}; - -class kernel_config { -public: - kernel_config( dim3 GridDim, dim3 BlockDim, size_t sharedMem, struct CUstream_st *stream ) - { - m_GridDim=GridDim; - m_BlockDim=BlockDim; - m_sharedMem=sharedMem; - m_stream = stream; - } - kernel_config() - { - m_GridDim=dim3(-1,-1,-1); - m_BlockDim=dim3(-1,-1,-1); - m_sharedMem=0; - m_stream =NULL; - } - void set_arg( const void *arg, size_t size, size_t offset ) - { - m_args.push_front( gpgpu_ptx_sim_arg(arg,size,offset) ); - } - dim3 grid_dim() const { return m_GridDim; } - dim3 block_dim() const { return m_BlockDim; } - void set_grid_dim(dim3 *d) { m_GridDim = *d; } - void set_block_dim(dim3 *d) { m_BlockDim = *d; } - gpgpu_ptx_sim_arg_list_t get_args() { return m_args; } - struct CUstream_st *get_stream() { return m_stream; } - -private: - dim3 m_GridDim; - dim3 m_BlockDim; - size_t m_sharedMem; - struct CUstream_st *m_stream; - gpgpu_ptx_sim_arg_list_t m_args; -}; - -struct _cuda_device_id *GPGPUSim_Init() +struct _cuda_device_id *gpgpu_context::GPGPUSim_Init() { - static _cuda_device_id *the_device = NULL; + //static _cuda_device_id *the_device = NULL; + _cuda_device_id *the_device = GPGPUsim_ctx_ptr()->the_cude_device; if( !the_device ) { gpgpu_sim *the_gpu = gpgpu_ptx_sim_init_perf(); @@ -393,7 +245,8 @@ struct _cuda_device_id *GPGPUSim_Init() prop->maxThreadsPerMultiProcessor = the_gpu->threads_per_core(); #endif the_gpu->set_prop(prop); - the_device = new _cuda_device_id(the_gpu); + GPGPUsim_ctx_ptr()->the_cude_device = new _cuda_device_id(the_gpu); + the_device = GPGPUsim_ctx_ptr()->the_cude_device; } start_sim_thread(1); return the_device; @@ -401,15 +254,27 @@ struct _cuda_device_id *GPGPUSim_Init() static CUctx_st* GPGPUSim_Context() { - static CUctx_st *the_context = NULL; + //static CUctx_st *the_context = NULL; + gpgpu_context *cur_ctx = GPGPU_Context(); + CUctx_st *the_context = GPGPUsim_ctx_ptr()->the_context; if( the_context == NULL ) { - _cuda_device_id *the_gpu = GPGPUSim_Init(); - the_context = new CUctx_st(the_gpu); + _cuda_device_id *the_gpu = cur_ctx->GPGPUSim_Init(); + GPGPUsim_ctx_ptr()->the_context = new CUctx_st(the_gpu); + the_context = GPGPUsim_ctx_ptr()->the_context; } return the_context; } - void ptxinfo_addinfo() +gpgpu_context* GPGPU_Context() +{ + static gpgpu_context *gpgpu_ctx = NULL; + if( gpgpu_ctx == NULL ) { + gpgpu_ctx = new gpgpu_context(); + } + return gpgpu_ctx; +} + + void ptxinfo_data::ptxinfo_addinfo() { if(!get_ptxinfo_kname()){ /* This info is not per kernel (since CUDA 5.0 some info (e.g. gmem, and cmem) is added at the beginning for the whole binary ) */ @@ -480,29 +345,618 @@ typedef std::map<unsigned,CUevent_st*> event_tracker_t; int CUevent_st::m_next_event_uid; event_tracker_t g_timer_events; -int g_active_device = 0; //active gpu that runs the code -std::list<kernel_config> g_cuda_launch_stack; -/******************************************************************************* - * * - * * - * * - *******************************************************************************/ +extern int cuobjdump_lex_init(yyscan_t* scanner); +extern void cuobjdump_set_in (FILE * _in_str ,yyscan_t yyscanner ); +extern int cuobjdump_parse(yyscan_t scanner, struct cuobjdump_parser* parser, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +extern int cuobjdump_lex_destroy(yyscan_t scanner); + +enum cuobjdumpSectionType { + PTXSECTION=0, + ELFSECTION +}; + + +// sectiontype: 0 for ptx, 1 for elf +void addCuobjdumpSection(int sectiontype, std::list<cuobjdumpSection*> &cuobjdumpSectionList){ + if (sectiontype) + cuobjdumpSectionList.push_front(new cuobjdumpELFSection()); + else + cuobjdumpSectionList.push_front(new cuobjdumpPTXSection()); + printf("## Adding new section %s\n", sectiontype?"ELF":"PTX"); +} + +void setCuobjdumparch(const char* arch, std::list<cuobjdumpSection*> &cuobjdumpSectionList){ + unsigned archnum; + sscanf(arch, "sm_%u", &archnum); + assert (archnum && "cannot have sm_0"); + printf("Adding arch: %s\n", arch); + cuobjdumpSectionList.front()->setArch(archnum); +} + +void setCuobjdumpidentifier(const char* identifier, std::list<cuobjdumpSection*> &cuobjdumpSectionList){ + printf("Adding identifier: %s\n", identifier); + cuobjdumpSectionList.front()->setIdentifier(identifier); +} + +void setCuobjdumpptxfilename(const char* filename, std::list<cuobjdumpSection*> &cuobjdumpSectionList){ + printf("Adding ptx filename: %s\n", filename); + cuobjdumpSection* x = cuobjdumpSectionList.front(); + if (dynamic_cast<cuobjdumpPTXSection*>(x) == NULL){ + assert (0 && "You shouldn't be trying to add a ptxfilename to an elf section"); + } + (dynamic_cast<cuobjdumpPTXSection*>(x))->setPTXfilename(filename); +} + +void setCuobjdumpelffilename(const char* filename, std::list<cuobjdumpSection*> &cuobjdumpSectionList){ + if (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()) == NULL){ + assert (0 && "You shouldn't be trying to add a elffilename to an ptx section"); + } + (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()))->setELFfilename(filename); +} + +void setCuobjdumpsassfilename(const char* filename, std::list<cuobjdumpSection*> &cuobjdumpSectionList){ + if (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()) == NULL){ + assert (0 && "You shouldn't be trying to add a sassfilename to an ptx section"); + } + (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()))->setSASSfilename(filename); +} + +//! Return the executable file of the process containing the PTX/SASS code +//! +//! This Function returns the executable file ran by the process. This +//! executable is supposed to contain the PTX/SASS code. It provides workaround +//! for processes running on valgrind by dereferencing /proc/<pid>/exe within the +//! GPGPU-Sim process before calling cuobjdump to extract PTX/SASS. This is +//! needed because valgrind uses x86 emulation to detect memory leak. Other +//! processes (e.g. cuobjdump) reading /proc/<pid>/exe will see the emulator +//! executable instead of the application binary. +//! +std::string get_app_binary(){ + char self_exe_path[1025]; +#ifdef __APPLE__ + uint32_t size = sizeof(self_exe_path); + if( _NSGetExecutablePath(self_exe_path,&size) != 0 ) { + printf("GPGPU-Sim ** ERROR: _NSGetExecutablePath input buffer too small\n"); + exit(1); + } +#else + std::stringstream exec_link; + exec_link << "/proc/self/exe"; + + ssize_t path_length = readlink(exec_link.str().c_str(), self_exe_path, 1024); + assert(path_length != -1); + self_exe_path[path_length] = '\0'; +#endif + + printf("self exe links to: %s\n", self_exe_path); + return self_exe_path; +} + +//above func gives abs path whereas this give just the name of application. +char* get_app_binary_name(std::string abs_path){ + char *self_exe_path; +#ifdef __APPLE__ + //TODO: get apple device and check the result. + printf("WARNING: not tested for Apple-mac devices \n"); + abort(); +#else + char* buf = strdup(abs_path.c_str()); + char *token = strtok(buf, "/"); + while(token !=NULL){ + self_exe_path = token; + token = strtok(NULL,"/"); + } +#endif + self_exe_path = strtok(self_exe_path, "."); + printf("self exe links to: %s\n", self_exe_path); + return self_exe_path; +} + +static int get_app_cuda_version() { + int app_cuda_version = 0; + char fname[1024]; + snprintf(fname,1024,"_app_cuda_version_XXXXXX"); + int fd=mkstemp(fname); + close(fd); + std::string app_cuda_version_command = "ldd " + get_app_binary() + " | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " + fname; + system(app_cuda_version_command.c_str()); + FILE * cmd = fopen(fname, "r"); + char buf[256]; + while (fgets(buf, sizeof(buf), cmd) != 0) { + std::cout << buf; + app_cuda_version = atoi(buf); + } + fclose(cmd); + if ( app_cuda_version == 0 ) { + printf( "Error - Cannot detect the app's CUDA version.\n" ); + exit(1); + } + return app_cuda_version; +} + +//! Keep track of the association between filename and cubin handle +void cuda_runtime_api::cuobjdumpRegisterFatBinary(unsigned int handle, const char* filename, CUctx_st *context){ + fatbinmap[handle] = filename; +} + -extern "C" { /******************************************************************************* - * * - * * - * * + * Add internal cuda runtime API call to accept gpgpu_context * *******************************************************************************/ -cudaError_t cudaPeekAtLastError(void) +cudaError_t cudaSetDeviceInternal(int device, gpgpu_context* gpgpu_ctx = NULL) { - return g_last_cudaError; + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + //set the active device to run cuda + if ( device <= ctx->GPGPUSim_Init()->num_devices() ) { + ctx->api->g_active_device = device; + return g_last_cudaError = cudaSuccess; + } else { + return g_last_cudaError = cudaErrorInvalidDevice; + } } -__host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size) +cudaError_t cudaGetDeviceInternal(int *device, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + *device = ctx->api->g_active_device; + return g_last_cudaError = cudaSuccess; +} + +__host__ cudaError_t CUDARTAPI cudaDeviceGetLimitInternal( size_t* pValue, cudaLimit limit, gpgpu_context* gpgpu_ctx = NULL ) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + _cuda_device_id *dev = ctx->GPGPUSim_Init(); + const struct cudaDeviceProp *prop = dev->get_prop(); + const gpgpu_sim_config& config=dev->get_gpgpu()->get_config(); + switch(limit) { + case 0: // cudaLimitStackSize + *pValue=config.stack_limit(); + break; + case 2: // cudaLimitMallocHeapSize + *pValue=config.heap_limit(); + break; +#if (CUDART_VERSION > 5050) + case 3: // cudaLimitDevRuntimeSyncDepth + if(prop->major > 2){ + *pValue=config.sync_depth_limit(); + break; + } + else{ + printf("ERROR:Limit %s is not supported on this architecture \n",limit); + abort(); + } + case 4: // cudaLimitDevRuntimePendingLaunchCount + if(prop->major > 2){ + *pValue=config.pending_launch_count_limit(); + break; + } + else{ + printf("ERROR:Limit %s is not supported on this architecture \n",limit); + abort(); + } +#endif + default: + printf("ERROR:Limit %s unimplemented \n",limit); + abort(); + } + return g_last_cudaError = cudaSuccess; + +} + + +void** cudaRegisterFatBinaryInternal( void *fatCubin, gpgpu_context* gpgpu_ctx = NULL) { + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } +#if (CUDART_VERSION < 2010) + printf("GPGPU-Sim PTX: ERROR ** this version of GPGPU-Sim requires CUDA 2.1 or higher\n"); + exit(1); +#endif + CUctx_st *context = GPGPUSim_Context(); + static unsigned next_fat_bin_handle = 1; + if(context->get_device()->get_gpgpu()->get_config().use_cuobjdump()) { + // The following workaround has only been verified on 64-bit systems. + if (sizeof(void*) == 4) + printf("GPGPU-Sim PTX: FatBin file name extraction has not been tested on 32-bit system.\n"); + + // This code will get the CUDA version the app was compiled with. + // We need this to determine how to handle the parsing of the binary. + // Making this a runtime variable based on the app, enables GPGPU-Sim compiled + // with a newer version of CUDA to run apps compiled with older versions of + // CUDA. This is especially useful for PTXPLUS execution. + //Skip cuda version check for pytorch application + std::string app_binary_path = get_app_binary(); + int pos = app_binary_path.find("python"); + if (pos==std::string::npos){ + // Not pytorch app : checking cuda version + int app_cuda_version = get_app_cuda_version(); + assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator." ); + } + + //int app_cuda_version = get_app_cuda_version(); + //assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator." ); + const char* filename; +#if CUDART_VERSION < 6000 + // FatBin handle from the .fatbin.c file (one of the intermediate files generated by NVCC) + typedef struct {int m; int v; const unsigned long long* d; char* f;} __fatDeviceText __attribute__ ((aligned (8))); + __fatDeviceText * fatDeviceText = (__fatDeviceText *) fatCubin; + + // Extract the source code file name that generate the given FatBin. + // - Obtains the pointer to the actual fatbin structure from the FatBin handle (fatCubin). + // - An integer inside the fatbin structure contains the relative offset to the source code file name. + // - This offset differs among different CUDA and GCC versions. + char * pfatbin = (char*) fatDeviceText->d; + int offset = *((int*)(pfatbin+48)); + filename = (pfatbin+16+offset); +#else + filename = "default"; +#endif + + // The extracted file name is associated with a fat_cubin_handle passed + // into cudaLaunch(). Inside cudaLaunch(), the associated file name is + // used to find the PTX/SASS section from cuobjdump, which contains the + // PTX/SASS code for the launched kernel function. + // This allows us to work around the fact that cuobjdump only outputs the + // file name associated with each section. + unsigned long long fat_cubin_handle = next_fat_bin_handle; + next_fat_bin_handle++; + printf("GPGPU-Sim PTX: __cudaRegisterFatBinary, fat_cubin_handle = %llu, filename=%s\n", fat_cubin_handle, filename); + /*! + * This function extracts all data from all files in first call + * then for next calls, only returns the appropriate number + */ + assert(fat_cubin_handle >= 1); + if (fat_cubin_handle==1) ctx->api->cuobjdumpInit(); + ctx->api->cuobjdumpRegisterFatBinary(fat_cubin_handle, filename, context); + + return (void**)fat_cubin_handle; + } +#if (CUDART_VERSION < 8000) + else { + static unsigned source_num=1; + unsigned long long fat_cubin_handle = next_fat_bin_handle++; + __cudaFatCudaBinary *info = (__cudaFatCudaBinary *)fatCubin; + assert( info->version >= 3 ); + unsigned num_ptx_versions=0; + unsigned max_capability=0; + unsigned selected_capability=0; + bool found=false; + unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_config().get_forced_max_capability(); + if (!info->ptx){ + printf("ERROR: Cannot find ptx code in cubin file\n" + "\tIf you are using CUDA 4.0 or higher, please enable -gpgpu_ptx_use_cuobjdump or downgrade to CUDA 3.1\n"); + exit(1); + } + while( info->ptx[num_ptx_versions].gpuProfileName != NULL ) { + unsigned capability=0; + sscanf(info->ptx[num_ptx_versions].gpuProfileName,"compute_%u",&capability); + printf("GPGPU-Sim PTX: __cudaRegisterFatBinary found PTX versions for '%s', ", info->ident); + printf("capability = %s\n", info->ptx[num_ptx_versions].gpuProfileName ); + if( forced_max_capability ) { + if( capability > max_capability && capability <= forced_max_capability ) { + found = true; + max_capability=capability; + selected_capability = num_ptx_versions; + } + } else { + if( capability > max_capability ) { + found = true; + max_capability=capability; + selected_capability = num_ptx_versions; + } + } + num_ptx_versions++; + } + if( found ) { + printf("GPGPU-Sim PTX: Loading PTX for %s, capability = %s\n", + info->ident, info->ptx[selected_capability].gpuProfileName ); + symbol_table *symtab; + const char *ptx = info->ptx[selected_capability].ptx; + if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) { + printf("GPGPU-Sim PTX: ERROR ** PTXPlus is only supported through cuobjdump\n" + "\tEither enable cuobjdump or disable PTXPlus in your configuration file\n"); + exit(1); + } else { + symtab=ctx->gpgpu_ptx_sim_load_ptx_from_string(ptx,source_num); + context->add_binary(symtab,fat_cubin_handle); + ctx->gpgpu_ptxinfo_load_from_string( ptx, source_num, max_capability, context->no_of_ptx ); + } + source_num++; + ctx->api->load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); + ctx->api->load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); + } else { + printf("GPGPU-Sim PTX: warning -- did not find an appropriate PTX in cubin\n"); + } + return (void**)fat_cubin_handle; + } +#else + else { + printf("ERROR ** __cudaRegisterFatBinary() needs to be updated\n"); + abort(); + } +#endif +} + +void cudaRegisterFunctionInternal( + void **fatCubinHandle, + const char *hostFun, + char *deviceFun, + const char *deviceName, + int thread_limit, + uint3 *tid, + uint3 *bid, + dim3 *bDim, + dim3 *gDim, + gpgpu_context *gpgpu_ctx = NULL +) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + CUctx_st *context = GPGPUSim_Context(); + unsigned fat_cubin_handle = (unsigned)(unsigned long long)fatCubinHandle; + printf("GPGPU-Sim PTX: __cudaRegisterFunction %s : hostFun 0x%p, fat_cubin_handle = %u\n", + deviceFun, hostFun, fat_cubin_handle); + if(context->get_device()->get_gpgpu()->get_config().use_cuobjdump()) + ctx->cuobjdumpParseBinary(fat_cubin_handle); + context->register_function( fat_cubin_handle, hostFun, deviceFun ); +} + +void cudaRegisterVarInternal( + void **fatCubinHandle, + char *hostVar, //pointer to...something + char *deviceAddress, //name of variable + const char *deviceName, //name of variable (same as above) + int ext, + int size, + int constant, + int global, + gpgpu_context *gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + printf("GPGPU-Sim PTX: __cudaRegisterVar: hostVar = %p; deviceAddress = %s; deviceName = %s\n", hostVar, deviceAddress, deviceName); + printf("GPGPU-Sim PTX: __cudaRegisterVar: Registering const memory space of %d bytes\n", size); + if(GPGPUSim_Context()->get_device()->get_gpgpu()->get_config().use_cuobjdump()) + ctx->cuobjdumpParseBinary((unsigned)(unsigned long long)fatCubinHandle); + fflush(stdout); + if ( constant && !global && !ext ) { + ctx->func_sim->gpgpu_ptx_sim_register_const_variable(hostVar,deviceName,size); + } else if ( !constant && !global && !ext ) { + ctx->func_sim->gpgpu_ptx_sim_register_global_variable(hostVar,deviceName,size); + } else cuda_not_implemented(__my_func__,__LINE__); +} + +cudaError_t cudaConfigureCallInternal(dim3 gridDim, dim3 blockDim, size_t sharedMem, cudaStream_t stream, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + struct CUstream_st *s = (struct CUstream_st *)stream; + ctx->api->g_cuda_launch_stack.push_back( kernel_config(gridDim,blockDim,sharedMem,s) ); + return g_last_cudaError = cudaSuccess; +} + +__host__ cudaError_t CUDARTAPI cudaGetDeviceCountInternal(int *count, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + _cuda_device_id *dev = ctx->GPGPUSim_Init(); + *count = dev->num_devices(); + return g_last_cudaError = cudaSuccess; +} + +__host__ cudaError_t CUDARTAPI cudaGetDevicePropertiesInternal(struct cudaDeviceProp *prop, int device, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + _cuda_device_id *dev = ctx->GPGPUSim_Init(); + if (device <= dev->num_devices() ) { + *prop= *dev->get_prop(); + return g_last_cudaError = cudaSuccess; + } else { + return g_last_cudaError = cudaErrorInvalidDevice; + } +} + + +__host__ cudaError_t CUDARTAPI cudaChooseDeviceInternal(int *device, const struct cudaDeviceProp *prop, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + _cuda_device_id *dev = ctx->GPGPUSim_Init(); + *device = dev->get_id(); + return g_last_cudaError = cudaSuccess; +} + +cudaError_t cudaSetupArgumentInternal(const void *arg, size_t size, size_t offset, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + gpgpusim_ptx_assert( !ctx->api->g_cuda_launch_stack.empty(), "empty launch stack" ); + kernel_config &config = ctx->api->g_cuda_launch_stack.back(); + config.set_arg(arg,size,offset); + printf("GPGPU-Sim PTX: Setting up arguments for %zu bytes starting at 0x%llx..\n",size, (unsigned long long) arg); + + return g_last_cudaError = cudaSuccess; +} + +cudaError_t cudaLaunchInternal( const char *hostFun, gpgpu_context* gpgpu_ctx = NULL ) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + CUctx_st* context = GPGPUSim_Context(); + char *mode = getenv("PTX_SIM_MODE_FUNC"); + if( mode ) + sscanf(mode,"%u", &(ctx->func_sim->g_ptx_sim_mode)); + gpgpusim_ptx_assert( !ctx->api->g_cuda_launch_stack.empty(), "empty launch stack" ); + kernel_config config = ctx->api->g_cuda_launch_stack.back(); + { + dim3 gridDim = config.grid_dim(); + dim3 blockDim = config.block_dim(); + if (gridDim.x * gridDim.y * gridDim.z == 0 || blockDim.x * blockDim.y * blockDim.z == 0) + { + //can't launch + printf("can't launch a empty kernel\n"); + ctx->api->g_cuda_launch_stack.pop_back(); + return g_last_cudaError = cudaErrorInvalidConfiguration; + } + } + struct CUstream_st *stream = config.get_stream(); + + printf("\nGPGPU-Sim PTX: cudaLaunch for 0x%p (mode=%s) on stream %u\n", hostFun, + (ctx->func_sim->g_ptx_sim_mode)?"functional simulation":"performance simulation", stream?stream->get_uid():0 ); + kernel_info_t *grid = ctx->api->gpgpu_cuda_ptx_sim_init_grid(hostFun,config.get_args(),config.grid_dim(),config.block_dim(),context); + //do dynamic PDOM analysis for performance simulation scenario + std::string kname = grid->name(); + function_info *kernel_func_info = grid->entry(); + if (kernel_func_info->is_pdom_set()) { + printf("GPGPU-Sim PTX: PDOM analysis already done for %s \n", kname.c_str() ); + } else { + printf("GPGPU-Sim PTX: finding reconvergence points for \'%s\'...\n", kname.c_str() ); + kernel_func_info->do_pdom(); + kernel_func_info->set_pdom(); + } + dim3 gridDim = config.grid_dim(); + dim3 blockDim = config.block_dim(); + + gpgpu_t *gpu = context->get_device()->get_gpgpu(); + checkpoint *g_checkpoint; + g_checkpoint = new checkpoint(); + class memory_space *global_mem; + global_mem = gpu->get_global_memory(); + + if(gpu->resume_option ==1 && (grid->get_uid()==gpu->resume_kernel)) + { + + char f1name[2048]; + snprintf(f1name,2048,"checkpoint_files/global_mem_%d.txt", grid->get_uid()); + + g_checkpoint->load_global_mem(global_mem, f1name); + for (int i=0;i<gpu->resume_CTA;i++) + grid->increment_cta_id(); + } + if(gpu->resume_option==1 && (grid->get_uid()<gpu->resume_kernel)) + { + char f1name[2048]; + snprintf(f1name,2048,"checkpoint_files/global_mem_%d.txt", grid->get_uid()); + + g_checkpoint->load_global_mem(global_mem, f1name); + printf("Skipping kernel %d as resuming from kernel %d\n",grid->get_uid(),gpu->resume_kernel ); + ctx->api->g_cuda_launch_stack.pop_back(); + return g_last_cudaError = cudaSuccess; + + } + if(gpu->checkpoint_option==1 && (grid->get_uid()>gpu->checkpoint_kernel)) + { + printf("Skipping kernel %d as checkpoint from kernel %d\n",grid->get_uid(),gpu->checkpoint_kernel ); + ctx->api->g_cuda_launch_stack.pop_back(); + return g_last_cudaError = cudaSuccess; + + } + printf("GPGPU-Sim PTX: pushing kernel \'%s\' to stream %u, gridDim= (%u,%u,%u) blockDim = (%u,%u,%u) \n", + kname.c_str(), stream?stream->get_uid():0, gridDim.x,gridDim.y,gridDim.z,blockDim.x,blockDim.y,blockDim.z ); + stream_operation op(grid,ctx->func_sim->g_ptx_sim_mode,stream); + g_stream_manager()->push(op); + ctx->api->g_cuda_launch_stack.pop_back(); + return g_last_cudaError = cudaSuccess; +} + +cudaError_t cudaMallocInternal(void **devPtr, size_t size, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } if(g_debug_execution >= 3){ announce_call(__my_func__); } @@ -510,7 +964,7 @@ __host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size) *devPtr = context->get_device()->get_gpgpu()->gpu_malloc(size); if(g_debug_execution >= 3){ printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n",size, (unsigned long long) *devPtr); - g_mallocPtr_Size[(unsigned long long)*devPtr] = size; + ctx->api->g_mallocPtr_Size[(unsigned long long)*devPtr] = size; } if ( *devPtr ) { return g_last_cudaError = cudaSuccess; @@ -519,20 +973,270 @@ __host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size) } } -__host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) +cudaError_t cudaMallocHostInternal(void **ptr, size_t size, gpgpu_context* gpgpu_ctx = NULL) { + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } if(g_debug_execution >= 3){ announce_call(__my_func__); } - GPGPUSim_Context(); *ptr = malloc(size); if ( *ptr ) { //track pinned memory size allocated in the host so that same amount of memory is also allocated in GPU. - pinned_memory_size[*ptr]=size; + ctx->api->pinned_memory_size[*ptr]=size; + return g_last_cudaError = cudaSuccess; + } else { + return g_last_cudaError = cudaErrorMemoryAllocation; + } +} + +cudaError_t cudaHostGetDevicePointerInternal(void **pDevice, void *pHost, unsigned int flags, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + //only cpu memory allocation happens in cudaHostAlloc. Linking with device pointer to pinned memory happens here. + //TODO: once kernel is executed, the contents in global pointer of GPU must be copied back to CPU host pointer! + flags=0; + CUctx_st* context = GPGPUSim_Context(); + gpgpu_t *gpu = context->get_device()->get_gpgpu(); + std::map<void *, size_t>::const_iterator i = ctx->api->pinned_memory_size.find(pHost); + assert(i != ctx->api->pinned_memory_size.end()); + size_t size = i->second; + *pDevice = gpu->gpu_malloc(size); + if(g_debug_execution >= 3){ + printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n",size, (unsigned long long) *pDevice); + ctx->api->g_mallocPtr_Size[(unsigned long long)*pDevice] = size; + } + if ( *pDevice ) { + ctx->api->pinned_memory[pHost]=pDevice; + //Copy contents in cpu to gpu + gpu->memcpy_to_gpu((size_t)*pDevice,pHost,size); + return g_last_cudaError = cudaSuccess; + } else { + return g_last_cudaError = cudaErrorMemoryAllocation; + } +} + +cudaError_t cudaGLMapBufferObjectInternal(void** devPtr, GLuint bufferObj, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } +#ifdef OPENGL_SUPPORT + GLint buffer_size=0; + CUctx_st* context = GPGPUSim_Context(); + + glbmap_entry_t *p = ctx->api->g_glbmap; + while ( p && p->m_bufferObj != bufferObj ) + p = p->m_next; + if ( p == NULL ) { + glBindBuffer(GL_ARRAY_BUFFER,bufferObj); + glGetBufferParameteriv(GL_ARRAY_BUFFER,GL_BUFFER_SIZE,&buffer_size); + assert( buffer_size != 0 ); + *devPtr = context->get_device()->get_gpgpu()->gpu_malloc(buffer_size); + + // create entry and insert to front of list + glbmap_entry_t *n = (glbmap_entry_t *) calloc(1,sizeof(glbmap_entry_t)); + n->m_next = ctx->api->g_glbmap; + ctx->api->g_glbmap = n; + + // initialize entry + n->m_bufferObj = bufferObj; + n->m_devPtr = *devPtr; + n->m_size = buffer_size; + + p = n; + } else { + buffer_size = p->m_size; + *devPtr = p->m_devPtr; + } + + if ( *devPtr ) { + char *data = (char *) calloc(p->m_size,1); + glGetBufferSubData(GL_ARRAY_BUFFER,0,buffer_size,data); + memcpy_to_gpu( (size_t) *devPtr, data, buffer_size ); + free(data); + printf("GPGPU-Sim PTX: cudaGLMapBufferObject %zu bytes starting at 0x%llx..\n", (size_t)buffer_size, + (unsigned long long) *devPtr); return g_last_cudaError = cudaSuccess; } else { return g_last_cudaError = cudaErrorMemoryAllocation; } + + return g_last_cudaError = cudaSuccess; +#else + fflush(stdout); + fflush(stderr); + printf("GPGPU-Sim PTX: GPGPU-Sim support for OpenGL integration disabled -- exiting\n"); + fflush(stdout); + exit(50); +#endif +} + +#if CUDART_VERSION >= 6050 +CUresult +cuLinkAddFileInternal(CUlinkState state, CUjitInputType type, const char *path, + unsigned int numOptions, CUjit_option *options, void **optionValues, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + static bool addedFile = false; + if (addedFile){ + printf("GPGPU-Sim PTX: ERROR: cuLinkAddFile does not support multiple files\n"); + abort(); + } + + //blocking + assert(type==CU_JIT_INPUT_PTX); + CUctx_st *context = GPGPUSim_Context(); + char *file = getenv("PTX_JIT_PATH"); + if(file==NULL){ + printf("GPGPU-Sim PTX: ERROR: PTX_JIT_PATH has not been set\n"); + abort(); + } + strcat(file,"/"); + strcat(file,path); + symbol_table *symtab = ctx->gpgpu_ptx_sim_load_ptx_from_filename( file ); + std::string fname(path); + ctx->api->name_symtab[fname] = symtab; + context->add_binary(symtab, 1); + ctx->api->load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); + ctx->api->load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); + addedFile = true; + return CUDA_SUCCESS; +} +#endif + +#if (CUDART_VERSION >= 2010) + +cudaError_t cudaHostAllocInternal(void **pHost, size_t bytes, unsigned int flags, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + *pHost = malloc(bytes); + //need to track the size allocated so that cudaHostGetDevicePointer() can function properly. + //TODO: vary this function behavior based on flags value (following nvidia documentation) + ctx->api->pinned_memory_size[*pHost]=bytes; + if( *pHost ) + return g_last_cudaError = cudaSuccess; + else + return g_last_cudaError = cudaErrorMemoryAllocation; +} + +#endif + +size_t getMaxThreadsPerBlock(struct cudaFuncAttributes *attr, gpgpu_context *ctx) { + _cuda_device_id *dev = ctx->GPGPUSim_Init(); + struct cudaDeviceProp prop; + + prop = *dev->get_prop(); + + size_t max = prop.maxThreadsPerBlock; + + if (attr->numRegs && (prop.regsPerBlock / attr->numRegs) < max) + max = prop.regsPerBlock / attr->numRegs; + + if (attr->sharedSizeBytes && (prop.sharedMemPerBlock / attr->sharedSizeBytes) < max) + max = prop.sharedMemPerBlock / attr->sharedSizeBytes; + + return max; +} + +cudaError_t CUDARTAPI cudaFuncGetAttributesInternal(struct cudaFuncAttributes *attr, const char *hostFun, gpgpu_context* gpgpu_ctx = NULL ) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + CUctx_st *context = GPGPUSim_Context(); + function_info *entry = context->get_kernel(hostFun); + if( entry ) { + const struct gpgpu_ptx_sim_info *kinfo = entry->get_kernel_info(); + attr->sharedSizeBytes = kinfo->smem; + attr->constSizeBytes = kinfo->cmem; + attr->localSizeBytes = kinfo->lmem; + attr->numRegs = kinfo->regs; + if(kinfo->maxthreads > 0) + attr->maxThreadsPerBlock = kinfo->maxthreads; + else + attr->maxThreadsPerBlock = getMaxThreadsPerBlock(attr, ctx); +#if CUDART_VERSION >= 3000 + attr->ptxVersion = kinfo->ptx_version; + attr->binaryVersion = kinfo->sm_target; +#endif + } + return g_last_cudaError = cudaSuccess; +} + + +/******************************************************************************* + * * + * * + * * + *******************************************************************************/ + +extern "C" { + +/******************************************************************************* + * * + * * + * * + *******************************************************************************/ +cudaError_t cudaPeekAtLastError(void) +{ + return g_last_cudaError; +} + +__host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size) +{ + return cudaMallocInternal(devPtr, size); +} + +__host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) +{ + return cudaMallocHostInternal(ptr, size); } __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, size_t *pitch, size_t width, size_t height) { @@ -617,21 +1321,21 @@ __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, size_t cou if(g_debug_execution >= 3) printf("GPGPU-Sim PTX: cudaMemcpy(): devPtr = %p\n", dst); if( kind == cudaMemcpyHostToDevice ) - g_stream_manager->push( stream_operation(src,(size_t)dst,count,0) ); + g_stream_manager()->push( stream_operation(src,(size_t)dst,count,0) ); else if( kind == cudaMemcpyDeviceToHost ) - g_stream_manager->push( stream_operation((size_t)src,dst,count,0) ); + g_stream_manager()->push( stream_operation((size_t)src,dst,count,0) ); else if( kind == cudaMemcpyDeviceToDevice ) - g_stream_manager->push( stream_operation((size_t)src,(size_t)dst,count,0) ); + g_stream_manager()->push( stream_operation((size_t)src,(size_t)dst,count,0) ); else if ( kind == cudaMemcpyDefault ) { if ((size_t)src >= GLOBAL_HEAP_START) { if ((size_t)dst >= GLOBAL_HEAP_START) - g_stream_manager->push( stream_operation((size_t)src,(size_t)dst,count,0) ); // device to device + g_stream_manager()->push( stream_operation((size_t)src,(size_t)dst,count,0) ); // device to device else - g_stream_manager->push( stream_operation((size_t)src,dst,count,0) ); // device to host + g_stream_manager()->push( stream_operation((size_t)src,dst,count,0) ); // device to host } else { if ((size_t)dst >= GLOBAL_HEAP_START) - g_stream_manager->push( stream_operation(src,(size_t)dst,count,0) ); + g_stream_manager()->push( stream_operation(src,(size_t)dst,count,0) ); else { printf("GPGPU-Sim PTX: cudaMemcpy - ERROR : unsupported transfer: host to host\n"); abort(); @@ -773,7 +1477,7 @@ __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol(const char *symbol, const void assert(kind == cudaMemcpyHostToDevice); printf("GPGPU-Sim PTX: cudaMemcpyToSymbol: symbol = %p\n", symbol); //stream_operation( const char *symbol, const void *src, size_t count, size_t offset ) - g_stream_manager->push( stream_operation(src,symbol,count,offset,0) ); + g_stream_manager()->push( stream_operation(src,symbol,count,offset,0) ); //gpgpu_ptx_sim_memcpy_symbol(symbol,src,count,offset,1,context->get_device()->get_gpgpu()); return g_last_cudaError = cudaSuccess; } @@ -787,7 +1491,7 @@ __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol(void *dst, const char *symbo //CUctx_st *context = GPGPUSim_Context(); assert(kind == cudaMemcpyDeviceToHost); printf("GPGPU-Sim PTX: cudaMemcpyFromSymbol: symbol = %p\n", symbol); - g_stream_manager->push( stream_operation(symbol,dst,count,offset,0) ); + g_stream_manager()->push( stream_operation(symbol,dst,count,offset,0) ); //gpgpu_ptx_sim_memcpy_symbol(symbol,dst,count,offset,0,context->get_device()->get_gpgpu()); return g_last_cudaError = cudaSuccess; } @@ -816,9 +1520,9 @@ __host__ cudaError_t CUDARTAPI cudaMemcpyAsync(void *dst, const void *src, size_ } struct CUstream_st *s = (struct CUstream_st *)stream; switch( kind ) { - case cudaMemcpyHostToDevice: g_stream_manager->push( stream_operation(src,(size_t)dst,count,s) ); break; - case cudaMemcpyDeviceToHost: g_stream_manager->push( stream_operation((size_t)src,dst,count,s) ); break; - case cudaMemcpyDeviceToDevice: g_stream_manager->push( stream_operation((size_t)src,(size_t)dst,count,s) ); break; + case cudaMemcpyHostToDevice: g_stream_manager()->push( stream_operation(src,(size_t)dst,count,s) ); break; + case cudaMemcpyDeviceToHost: g_stream_manager()->push( stream_operation((size_t)src,dst,count,s) ); break; + case cudaMemcpyDeviceToDevice: g_stream_manager()->push( stream_operation((size_t)src,(size_t)dst,count,s) ); break; default: abort(); } @@ -875,105 +1579,6 @@ __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync(void *dst, size_t dpit return g_last_cudaError = cudaErrorUnknown; } - - -/******************************************************************************* - * * - * * - * * - *******************************************************************************/ - -__host__ cudaError_t CUDARTAPI cudaMemset(void *mem, int c, size_t count) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - CUctx_st *context = GPGPUSim_Context(); - gpgpu_t *gpu = context->get_device()->get_gpgpu(); - gpu->gpu_memset((size_t)mem, c, count); - return g_last_cudaError = cudaSuccess; -} - -//memset operation is done but i think its not async? -__host__ cudaError_t CUDARTAPI cudaMemsetAsync(void *mem, int c, size_t count, cudaStream_t stream=0) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - printf("GPGPU-Sim PTX: WARNING: Asynchronous memset not supported (%s)\n", __my_func__); - CUctx_st *context = GPGPUSim_Context(); - gpgpu_t *gpu = context->get_device()->get_gpgpu(); - gpu->gpu_memset((size_t)mem, c, count); - return g_last_cudaError = cudaSuccess; -} - -__host__ cudaError_t CUDARTAPI cudaMemset2D(void *mem, size_t pitch, int c, size_t width, size_t height) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - cuda_not_implemented(__my_func__,__LINE__); - return g_last_cudaError = cudaErrorUnknown; -} - - - -/******************************************************************************* - * * - * * - * * - *******************************************************************************/ - -__host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, const char *symbol) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - cuda_not_implemented(__my_func__,__LINE__); - return g_last_cudaError = cudaErrorUnknown; -} - - -__host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, const char *symbol) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - cuda_not_implemented(__my_func__,__LINE__); - return g_last_cudaError = cudaErrorUnknown; -} - - - -/******************************************************************************* - * * - * * - * * - *******************************************************************************/ -__host__ cudaError_t CUDARTAPI cudaGetDeviceCount(int *count) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - _cuda_device_id *dev = GPGPUSim_Init(); - *count = dev->num_devices(); - return g_last_cudaError = cudaSuccess; -} - -__host__ cudaError_t CUDARTAPI cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - _cuda_device_id *dev = GPGPUSim_Init(); - if (device <= dev->num_devices() ) { - *prop= *dev->get_prop(); - return g_last_cudaError = cudaSuccess; - } else { - return g_last_cudaError = cudaErrorInvalidDevice; - } -} - #if (CUDART_VERSION >= 8000) cudaError_t CUDARTAPI cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int* numBlocks, const char *hostFunc, int blockSize, size_t dynamicSMemSize, unsigned int flags) { @@ -1003,13 +1608,38 @@ cudaError_t CUDARTAPI cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int #endif #if (CUDART_VERSION > 5000) -__host__ cudaError_t CUDARTAPI cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) + +/******************************************************************************* + * * + * * + * * + *******************************************************************************/ +__host__ cudaError_t CUDARTAPI cudaMemset(void *mem, int c, size_t count) { if(g_debug_execution >= 3){ announce_call(__my_func__); } + CUctx_st *context = GPGPUSim_Context(); + gpgpu_t *gpu = context->get_device()->get_gpgpu(); + gpu->gpu_memset((size_t)mem, c, count); + return g_last_cudaError = cudaSuccess; +} + +__host__ cudaError_t CUDARTAPI cudaDeviceGetAttributeInternal(int *value, enum cudaDeviceAttr attr, int device, gpgpu_context* gpgpu_ctx = NULL) +{ + gpgpu_context *ctx; + if (gpgpu_ctx){ + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + const struct cudaDeviceProp *prop; - _cuda_device_id *dev = GPGPUSim_Init(); + _cuda_device_id *dev = ctx->GPGPUSim_Init(); + if (device <= dev->num_devices() ) { prop = dev->get_prop(); switch (attr) { @@ -1193,82 +1823,98 @@ __host__ cudaError_t CUDARTAPI cudaDeviceGetAttribute(int *value, enum cudaDevic return g_last_cudaError = cudaErrorInvalidDevice; } } -#endif -__host__ cudaError_t CUDARTAPI cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) +//memset operation is done but i think its not async? +__host__ cudaError_t CUDARTAPI cudaMemsetAsync(void *mem, int c, size_t count, cudaStream_t stream=0) { if(g_debug_execution >= 3){ announce_call(__my_func__); } - _cuda_device_id *dev = GPGPUSim_Init(); - *device = dev->get_id(); + printf("GPGPU-Sim PTX: WARNING: Asynchronous memset not supported (%s)\n", __my_func__); + CUctx_st *context = GPGPUSim_Context(); + gpgpu_t *gpu = context->get_device()->get_gpgpu(); + gpu->gpu_memset((size_t)mem, c, count); return g_last_cudaError = cudaSuccess; } -__host__ cudaError_t CUDARTAPI cudaSetDevice(int device) +__host__ cudaError_t CUDARTAPI cudaMemset2D(void *mem, size_t pitch, int c, size_t width, size_t height) { if(g_debug_execution >= 3){ announce_call(__my_func__); } - //set the active device to run cuda - if ( device <= GPGPUSim_Init()->num_devices() ) { - g_active_device = device; - return g_last_cudaError = cudaSuccess; - } else { - return g_last_cudaError = cudaErrorInvalidDevice; - } + cuda_not_implemented(__my_func__,__LINE__); + return g_last_cudaError = cudaErrorUnknown; } -__host__ cudaError_t CUDARTAPI cudaGetDevice(int *device) + + +/******************************************************************************* + * * + * * + * * + *******************************************************************************/ + +__host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, const char *symbol) { if(g_debug_execution >= 3){ announce_call(__my_func__); } - *device = g_active_device; - return g_last_cudaError = cudaSuccess; + cuda_not_implemented(__my_func__,__LINE__); + return g_last_cudaError = cudaErrorUnknown; } -__host__ cudaError_t CUDARTAPI cudaDeviceGetLimit ( size_t* pValue, cudaLimit limit ) + +__host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, const char *symbol) { if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - _cuda_device_id *dev = GPGPUSim_Init(); - const struct cudaDeviceProp *prop = dev->get_prop(); - const gpgpu_sim_config& config=dev->get_gpgpu()->get_config(); - switch(limit) { - case 0: // cudaLimitStackSize - *pValue=config.stack_limit(); - break; - case 2: // cudaLimitMallocHeapSize - *pValue=config.heap_limit(); - break; -#if (CUDART_VERSION > 5050) - case 3: // cudaLimitDevRuntimeSyncDepth - if(prop->major > 2){ - *pValue=config.sync_depth_limit(); - break; - } - else{ - printf("ERROR:Limit %s is not supported on this architecture \n",limit); - abort(); - } - case 4: // cudaLimitDevRuntimePendingLaunchCount - if(prop->major > 2){ - *pValue=config.pending_launch_count_limit(); - break; - } - else{ - printf("ERROR:Limit %s is not supported on this architecture \n",limit); - abort(); - } + announce_call(__my_func__); + } + cuda_not_implemented(__my_func__,__LINE__); + return g_last_cudaError = cudaErrorUnknown; +} + + + +/******************************************************************************* + * * + * * + * * + *******************************************************************************/ +__host__ cudaError_t CUDARTAPI cudaGetDeviceCount(int *count) +{ + return cudaGetDeviceCountInternal(count); +} + +__host__ cudaError_t CUDARTAPI cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) +{ + return cudaGetDevicePropertiesInternal(prop, device); +} + +#if (CUDART_VERSION > 5000) +__host__ cudaError_t CUDARTAPI cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) +{ + return cudaDeviceGetAttributeInternal(value, attr, device); +} #endif - default: - printf("ERROR:Limit %s unimplemented \n",limit); - abort(); - } - return g_last_cudaError = cudaSuccess; +__host__ cudaError_t CUDARTAPI cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) +{ + return cudaChooseDeviceInternal(device, prop); +} + +__host__ cudaError_t CUDARTAPI cudaSetDevice(int device) +{ + return cudaSetDeviceInternal(device); +} + +__host__ cudaError_t CUDARTAPI cudaGetDevice(int *device) +{ + return cudaGetDeviceInternal(device); +} + +__host__ cudaError_t CUDARTAPI cudaDeviceGetLimit( size_t* pValue, cudaLimit limit ) +{ + return cudaDeviceGetLimitInternal( pValue, limit ); } __host__ cudaError_t CUDARTAPI cudaStreamGetPriority ( cudaStream_t hStream, int* priority ) @@ -1466,131 +2112,35 @@ __host__ const char* CUDARTAPI cudaGetErrorString(cudaError_t error) return strdup(buf); } -__host__ cudaError_t CUDARTAPI cudaConfigureCall(dim3 gridDim, dim3 blockDim, size_t sharedMem, cudaStream_t stream) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - struct CUstream_st *s = (struct CUstream_st *)stream; - g_cuda_launch_stack.push_back( kernel_config(gridDim,blockDim,sharedMem,s) ); - return g_last_cudaError = cudaSuccess; -} - __host__ cudaError_t CUDARTAPI cudaSetupArgument(const void *arg, size_t size, size_t offset) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - gpgpusim_ptx_assert( !g_cuda_launch_stack.empty(), "empty launch stack" ); - kernel_config &config = g_cuda_launch_stack.back(); - config.set_arg(arg,size,offset); - printf("GPGPU-Sim PTX: Setting up arguments for %zu bytes starting at 0x%llx..\n",size, (unsigned long long) arg); - - return g_last_cudaError = cudaSuccess; + return cudaSetupArgumentInternal(arg, size, offset); } __host__ cudaError_t CUDARTAPI cudaLaunch( const char *hostFun ) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - CUctx_st* context = GPGPUSim_Context(); - char *mode = getenv("PTX_SIM_MODE_FUNC"); - if( mode ) - sscanf(mode,"%u", &g_ptx_sim_mode); - gpgpusim_ptx_assert( !g_cuda_launch_stack.empty(), "empty launch stack" ); - kernel_config config = g_cuda_launch_stack.back(); - { - dim3 gridDim = config.grid_dim(); - dim3 blockDim = config.block_dim(); - //if (gridDim.x * gridDim.y * gridDim.z == 0 || blockDim.x * blockDim.y * blockDim.z == 0) - //{ - //can't launch - // printf("can't launch a empty kernel\n"); - // g_cuda_launch_stack.pop_back(); - // return g_last_cudaError = cudaErrorInvalidConfiguration; - //} - } - struct CUstream_st *stream = config.get_stream(); - if(g_stream_manager->is_blocking()) - stream = 0; - - printf("\nGPGPU-Sim PTX: cudaLaunch for 0x%p (mode=%s) on stream %u\n", hostFun, - g_ptx_sim_mode?"functional simulation":"performance simulation", stream?stream->get_uid():0 ); - kernel_info_t *grid = gpgpu_cuda_ptx_sim_init_grid(hostFun,config.get_args(),config.grid_dim(),config.block_dim(),context); - //do dynamic PDOM analysis for performance simulation scenario - std::string kname = grid->name(); - function_info *kernel_func_info = grid->entry(); - if (kernel_func_info->is_pdom_set()) { - printf("GPGPU-Sim PTX: PDOM analysis already done for %s \n", kname.c_str() ); - } else { - printf("GPGPU-Sim PTX: finding reconvergence points for \'%s\'...\n", kname.c_str() ); - kernel_func_info->do_pdom(); - kernel_func_info->set_pdom(); - } - dim3 gridDim = config.grid_dim(); - dim3 blockDim = config.block_dim(); - - gpgpu_t *gpu = context->get_device()->get_gpgpu(); - checkpoint *g_checkpoint; - g_checkpoint = new checkpoint(); - class memory_space *global_mem; - global_mem = gpu->get_global_memory(); - - if(gpu->resume_option ==1 && (grid->get_uid()==gpu->resume_kernel)) - { - - char f1name[2048]; - snprintf(f1name,2048,"checkpoint_files/global_mem_%d.txt", grid->get_uid()); - - g_checkpoint->load_global_mem(global_mem, f1name); - for (int i=0;i<gpu->resume_CTA;i++) - grid->increment_cta_id(); - } - if(gpu->resume_option==1 && (grid->get_uid()<gpu->resume_kernel)) - { - char f1name[2048]; - snprintf(f1name,2048,"checkpoint_files/global_mem_%d.txt", grid->get_uid()); - - g_checkpoint->load_global_mem(global_mem, f1name); - printf("Skipping kernel %d as resuming from kernel %d\n",grid->get_uid(),gpu->resume_kernel ); - g_cuda_launch_stack.pop_back(); - return g_last_cudaError = cudaSuccess; - - } - if(gpu->checkpoint_option==1 && (grid->get_uid()>gpu->checkpoint_kernel)) - { - printf("Skipping kernel %d as checkpoint from kernel %d\n",grid->get_uid(),gpu->checkpoint_kernel ); - g_cuda_launch_stack.pop_back(); - return g_last_cudaError = cudaSuccess; - - } - printf("GPGPU-Sim PTX: pushing kernel \'%s\' to stream %u, gridDim= (%u,%u,%u) blockDim = (%u,%u,%u) \n", - kname.c_str(), stream?stream->get_uid():0, gridDim.x,gridDim.y,gridDim.z,blockDim.x,blockDim.y,blockDim.z ); - stream_operation op(grid,g_ptx_sim_mode,stream); - g_stream_manager->push(op); - g_cuda_launch_stack.pop_back(); - return g_last_cudaError = cudaSuccess; + return cudaLaunchInternal( hostFun ); } __host__ cudaError_t CUDARTAPI cudaLaunchKernel ( const char* hostFun, dim3 gridDim, dim3 blockDim, const void** args, size_t sharedMem, cudaStream_t stream ) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - CUctx_st *context = GPGPUSim_Context(); - function_info *entry = context->get_kernel(hostFun); - - cudaConfigureCall(gridDim, blockDim, sharedMem, stream); - for(unsigned i = 0; i < entry->num_args(); i++){ - std::pair<size_t, unsigned> p = entry->get_param_config(i); - cudaSetupArgument(args[i], p.first, p.second); - } + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + CUctx_st *context = GPGPUSim_Context(); + function_info *entry = context->get_kernel(hostFun); +#if CUDART_VERSION < 10000 + cudaConfigureCallInternal(gridDim, blockDim, sharedMem, stream); +#endif + for(unsigned i = 0; i < entry->num_args(); i++){ + std::pair<size_t, unsigned> p = entry->get_param_config(i); + cudaSetupArgumentInternal(args[i], p.first, p.second); + } - cudaLaunch(hostFun); - return g_last_cudaError = cudaSuccess; + cudaLaunchInternal(hostFun); + return g_last_cudaError = cudaSuccess; } @@ -1608,7 +2158,7 @@ __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *stream) printf("GPGPU-Sim PTX: cudaStreamCreate\n"); #if (CUDART_VERSION >= 3000) *stream = new struct CUstream_st(); - g_stream_manager->add_stream(*stream); + g_stream_manager()->add_stream(*stream); #else *stream = 0; printf("GPGPU-Sim PTX: WARNING: Asynchronous kernel execution not supported (%s)\n", __my_func__); @@ -1647,7 +2197,7 @@ __host__ cudaError_t CUDARTAPI cudaStreamDestroy(cudaStream_t stream) //per-stream synchronization required for application using external libraries without explicit synchronization in the code to //avoid the stream_manager from spinning forever to destroy non-empty streams without making any forward progress. stream->synchronize(); - g_stream_manager->destroy_stream(stream); + g_stream_manager()->destroy_stream(stream); #endif return g_last_cudaError = cudaSuccess; } @@ -1727,7 +2277,7 @@ __host__ cudaError_t CUDARTAPI cudaEventRecord(cudaEvent_t event, cudaStream_t s if( !e ) return g_last_cudaError = cudaErrorUnknown; struct CUstream_st *s = (struct CUstream_st *)stream; stream_operation op(e,s); - g_stream_manager->push(op); + g_stream_manager()->push(op); return g_last_cudaError = cudaSuccess; } @@ -1743,11 +2293,11 @@ __host__ cudaError_t CUDARTAPI cudaStreamWaitEvent(cudaStream_t stream, cudaEven return g_last_cudaError = cudaSuccess; } if (!stream){ - g_stream_manager->pushCudaStreamWaitEventToAllStreams(e, flags); + g_stream_manager()->pushCudaStreamWaitEventToAllStreams(e, flags); } else { struct CUstream_st *s = (struct CUstream_st *)stream; stream_operation op(s,e,flags); - g_stream_manager->push(op); + g_stream_manager()->push(op); } return g_last_cudaError = cudaSuccess; } @@ -1898,178 +2448,8 @@ __host__ cudaError_t CUDARTAPI cudaGetExportTable(const void **ppExportTable, co //#include "../../cuobjdump_to_ptxplus/cuobjdump_parser.h" -enum cuobjdumpSectionType { - PTXSECTION=0, - ELFSECTION -}; - - -class cuobjdumpSection { -public: - //Constructor - cuobjdumpSection() { - arch = 0; - identifier = ""; - } - virtual ~cuobjdumpSection() {} - unsigned getArch() {return arch;} - void setArch(unsigned a) {arch = a;} - std::string getIdentifier() {return identifier;} - void setIdentifier(std::string i) {identifier = i;} - virtual void print(){std::cout << "cuobjdump Section: unknown type" << std::endl;} -private: - unsigned arch; - std::string identifier; -}; - -class cuobjdumpELFSection : public cuobjdumpSection -{ -public: - cuobjdumpELFSection() {} - virtual ~cuobjdumpELFSection() { - elffilename = ""; - sassfilename = ""; - } - std::string getELFfilename() {return elffilename;} - void setELFfilename(std::string f) {elffilename = f;} - std::string getSASSfilename() {return sassfilename;} - void setSASSfilename(std::string f) {sassfilename = f;} - virtual void print() { - std::cout << "ELF Section:" << std::endl; - std::cout << "arch: sm_" << getArch() << std::endl; - std::cout << "identifier: " << getIdentifier() << std::endl; - std::cout << "elf filename: " << getELFfilename() << std::endl; - std::cout << "sass filename: " << getSASSfilename() << std::endl; - std::cout << std::endl; - } -private: - std::string elffilename; - std::string sassfilename; -}; - -class cuobjdumpPTXSection : public cuobjdumpSection -{ -public: - cuobjdumpPTXSection(){ - ptxfilename = ""; - } - std::string getPTXfilename() {return ptxfilename;} - void setPTXfilename(std::string f) {ptxfilename = f;} - virtual void print() { - std::cout << "PTX Section:" << std::endl; - std::cout << "arch: sm_" << getArch() << std::endl; - std::cout << "identifier: " << getIdentifier() << std::endl; - std::cout << "ptx filename: " << getPTXfilename() << std::endl; - std::cout << std::endl; - } -private: - std::string ptxfilename; -}; - -std::list<cuobjdumpSection*> cuobjdumpSectionList; -std::list<cuobjdumpSection*> libSectionList; - -// sectiontype: 0 for ptx, 1 for elf -void addCuobjdumpSection(int sectiontype){ - if (sectiontype) - cuobjdumpSectionList.push_front(new cuobjdumpELFSection()); - else - cuobjdumpSectionList.push_front(new cuobjdumpPTXSection()); - printf("## Adding new section %s\n", sectiontype?"ELF":"PTX"); -} - -void setCuobjdumparch(const char* arch){ - unsigned archnum; - sscanf(arch, "sm_%u", &archnum); - assert (archnum && "cannot have sm_0"); - printf("Adding arch: %s\n", arch); - cuobjdumpSectionList.front()->setArch(archnum); -} - -void setCuobjdumpidentifier(const char* identifier){ - printf("Adding identifier: %s\n", identifier); - cuobjdumpSectionList.front()->setIdentifier(identifier); -} - -void setCuobjdumpptxfilename(const char* filename){ - printf("Adding ptx filename: %s\n", filename); - cuobjdumpSection* x = cuobjdumpSectionList.front(); - if (dynamic_cast<cuobjdumpPTXSection*>(x) == NULL){ - assert (0 && "You shouldn't be trying to add a ptxfilename to an elf section"); - } - (dynamic_cast<cuobjdumpPTXSection*>(x))->setPTXfilename(filename); -} - -void setCuobjdumpelffilename(const char* filename){ - if (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()) == NULL){ - assert (0 && "You shouldn't be trying to add a elffilename to an ptx section"); - } - (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()))->setELFfilename(filename); -} - -void setCuobjdumpsassfilename(const char* filename){ - if (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()) == NULL){ - assert (0 && "You shouldn't be trying to add a sassfilename to an ptx section"); - } - (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()))->setSASSfilename(filename); -} -extern int cuobjdump_parse(); -extern FILE *cuobjdump_in; - -//! Return the executable file of the process containing the PTX/SASS code -//! -//! This Function returns the executable file ran by the process. This -//! executable is supposed to contain the PTX/SASS code. It provides workaround -//! for processes running on valgrind by dereferencing /proc/<pid>/exe within the -//! GPGPU-Sim process before calling cuobjdump to extract PTX/SASS. This is -//! needed because valgrind uses x86 emulation to detect memory leak. Other -//! processes (e.g. cuobjdump) reading /proc/<pid>/exe will see the emulator -//! executable instead of the application binary. -//! -std::string get_app_binary(){ - char self_exe_path[1025]; -#ifdef __APPLE__ - uint32_t size = sizeof(self_exe_path); - if( _NSGetExecutablePath(self_exe_path,&size) != 0 ) { - printf("GPGPU-Sim ** ERROR: _NSGetExecutablePath input buffer too small\n"); - exit(1); - } -#else - std::stringstream exec_link; - exec_link << "/proc/self/exe"; - - ssize_t path_length = readlink(exec_link.str().c_str(), self_exe_path, 1024); - assert(path_length != -1); - self_exe_path[path_length] = '\0'; -#endif - - printf("self exe links to: %s\n", self_exe_path); - return self_exe_path; -} - -//above func gives abs path whereas this give just the name of application. -char* get_app_binary_name(std::string abs_path){ - char *self_exe_path; -#ifdef __APPLE__ - //TODO: get apple device and check the result. - printf("WARNING: not tested for Apple-mac devices \n"); - abort(); -#else - char* buf = strdup(abs_path.c_str()); - char *token = strtok(buf, "/"); - while(token !=NULL){ - self_exe_path = token; - token = strtok(NULL,"/"); - } -#endif - self_exe_path = strtok(self_exe_path, "."); - printf("self exe links to: %s\n", self_exe_path); - return self_exe_path; -} - //extracts all ptx files from binary and dumps into prog_name.unique_no.sm_<>.ptx files -void extract_ptx_files_using_cuobjdump(){ - extern bool g_cdp_enabled; +void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context){ char command[1000]; char *pytorch_bin = getenv("PYTORCH_BIN"); std::string app_binary = get_app_binary(); @@ -2090,7 +2470,7 @@ void extract_ptx_files_using_cuobjdump(){ printf("WARNING: Failed to execute cuobjdump to get list of ptx files \n"); exit(0); } - if(!g_cdp_enabled) { + if(!gpgpu_ctx->device_runtime->g_cdp_enabled) { //based on the list above, dump ptx files individually. Format of dumped ptx file is prog_name.unique_no.sm_<>.ptx std::ifstream infile(ptx_list_file_name); @@ -2105,11 +2485,11 @@ void extract_ptx_files_using_cuobjdump(){ printf("ERROR: command: %s failed \n",command); exit(0); } - no_of_ptx++; + context->no_of_ptx++; } } - if(!no_of_ptx){ + if(!context->no_of_ptx){ printf("WARNING: Number of ptx in the executable file are 0. One of the reasons might be\n"); printf("\t1. CDP is enabled\n"); printf("\t2. When using PyTorch, PYTORCH_BIN is not set correctly\n"); @@ -2137,28 +2517,6 @@ void extract_ptx_files_using_cuobjdump(){ } -static int get_app_cuda_version() { - int app_cuda_version = 0; - char fname[1024]; - snprintf(fname,1024,"_app_cuda_version_XXXXXX"); - int fd=mkstemp(fname); - close(fd); - std::string app_cuda_version_command = "ldd " + get_app_binary() + " | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " + fname; - system(app_cuda_version_command.c_str()); - FILE * cmd = fopen(fname, "r"); - char buf[256]; - while (fgets(buf, sizeof(buf), cmd) != 0) { - std::cout << buf; - app_cuda_version = atoi(buf); - } - fclose(cmd); - if ( app_cuda_version == 0 ) { - printf( "Error - Cannot detect the app's CUDA version.\n" ); - exit(1); - } - return app_cuda_version; -} - //! Call cuobjdump to extract everything (-elf -sass -ptx) /*! @@ -2168,7 +2526,7 @@ static int get_app_cuda_version() { * It is also responsible for extracting the libraries linked to the binary if the option is * enabled * */ -void extract_code_using_cuobjdump(){ +void cuda_runtime_api::extract_code_using_cuobjdump(){ CUctx_st *context = GPGPUSim_Context(); unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_config().get_forced_max_capability(); @@ -2185,12 +2543,11 @@ void extract_code_using_cuobjdump(){ } // Running cuobjdump using dynamic link to current process // Needs the option '-all' to extract PTX from CDP-enabled binary - extern bool g_cdp_enabled; //dump ptx for all individial ptx files into sepearte files which is later used by ptxas. int result=0; #if (CUDART_VERSION >= 6000) - extract_ptx_files_using_cuobjdump(); + extract_ptx_files_using_cuobjdump(context); return; #endif //TODO: redundant to dump twice. how can it be prevented? @@ -2200,7 +2557,7 @@ void extract_code_using_cuobjdump(){ snprintf(fname,1024,"_cuobjdump_complete_output_XXXXXX"); int fd=mkstemp(fname); close(fd); - if(!g_cdp_enabled) + if(!gpgpu_ctx->device_runtime->g_cdp_enabled) snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass %s > %s", app_binary.c_str(), fname); else snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass -all %s > %s", app_binary.c_str(), fname); @@ -2223,9 +2580,16 @@ void extract_code_using_cuobjdump(){ if (parse_output) { printf("Parsing file %s\n", fname); + FILE *cuobjdump_in; cuobjdump_in = fopen(fname, "r"); - cuobjdump_parse(); + struct cuobjdump_parser parser; + parser.elfserial = 1; + parser.ptxserial = 1; + cuobjdump_lex_init(&(parser.scanner)); + cuobjdump_set_in(cuobjdump_in, (parser.scanner)); + cuobjdump_parse(parser.scanner, &parser, cuobjdumpSectionList); + cuobjdump_lex_destroy(parser.scanner); fclose(cuobjdump_in); printf("Done parsing!!!\n"); } else { @@ -2273,8 +2637,15 @@ void extract_code_using_cuobjdump(){ std::cout << "Done" << std::endl; std::cout << "Trying to parse " << libcodfn.str() << std::endl; + FILE *cuobjdump_in; cuobjdump_in = fopen(libcodfn.str().c_str(), "r"); - cuobjdump_parse(); + struct cuobjdump_parser parser; + parser.elfserial = 1; + parser.ptxserial = 1; + cuobjdump_lex_init(&(parser.scanner)); + cuobjdump_set_in(cuobjdump_in, (parser.scanner)); + cuobjdump_parse(parser.scanner, &parser, cuobjdumpSectionList); + cuobjdump_lex_destroy(parser.scanner); fclose(cuobjdump_in); std::getline(libsf, line); } @@ -2324,7 +2695,7 @@ void printSectionList(std::list<cuobjdumpSection*> sl) { } //! Remove unecessary sm versions from the section list -std::list<cuobjdumpSection*> pruneSectionList(std::list<cuobjdumpSection*> cuobjdumpSectionList, CUctx_st *context) { +std::list<cuobjdumpSection*> cuda_runtime_api::pruneSectionList(CUctx_st *context) { unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_config().get_forced_max_capability(); //For ptxplus, force the max capability to 19 if it's higher or unspecified(0) @@ -2377,7 +2748,7 @@ std::list<cuobjdumpSection*> pruneSectionList(std::list<cuobjdumpSection*> cuobj } //! Merge all PTX sections that have a specific identifier into one file -std::list<cuobjdumpSection*> mergeMatchingSections(std::list<cuobjdumpSection*> cuobjdumpSectionList, std::string identifier){ +std::list<cuobjdumpSection*> cuda_runtime_api::mergeMatchingSections(std::string identifier){ const char *ptxcode = ""; std::list<cuobjdumpSection*>::iterator old_iter; cuobjdumpPTXSection* old_ptxsection = NULL; @@ -2420,7 +2791,7 @@ std::list<cuobjdumpSection*> mergeMatchingSections(std::list<cuobjdumpSection*> } //! Merge any PTX sections with matching identifiers -std::list<cuobjdumpSection*> mergeSections(std::list<cuobjdumpSection*> cuobjdumpSectionList){ +std::list<cuobjdumpSection*> cuda_runtime_api::mergeSections(){ std::vector<std::string> identifier; cuobjdumpPTXSection* ptxsection; @@ -2442,7 +2813,7 @@ std::list<cuobjdumpSection*> mergeSections(std::list<cuobjdumpSection*> cuobjdum for ( std::vector<std::string>::iterator iter = identifier.begin(); iter != identifier.end(); iter++) { - cuobjdumpSectionList = mergeMatchingSections(cuobjdumpSectionList, *iter); + cuobjdumpSectionList = mergeMatchingSections(*iter); } return cuobjdumpSectionList; @@ -2467,7 +2838,7 @@ cuobjdumpELFSection* findELFSectionInList(std::list<cuobjdumpSection*> sectionli } //! Find an ELF section in all the known lists -cuobjdumpELFSection* findELFSection(const std::string identifier){ +cuobjdumpELFSection* cuda_runtime_api::findELFSection(const std::string identifier){ cuobjdumpELFSection* sec = findELFSectionInList(cuobjdumpSectionList, identifier); if (sec!=NULL)return sec; sec = findELFSectionInList(libSectionList, identifier); @@ -2478,7 +2849,7 @@ cuobjdumpELFSection* findELFSection(const std::string identifier){ } //! Within the section list, find the PTX section corresponding to a given identifier -cuobjdumpPTXSection* findPTXSectionInList(std::list<cuobjdumpSection*> sectionlist, const std::string identifier){ +cuobjdumpPTXSection* cuda_runtime_api::findPTXSectionInList(std::list<cuobjdumpSection*> §ionlist, const std::string identifier){ std::list<cuobjdumpSection*>::iterator iter; for ( iter = sectionlist.begin(); iter != sectionlist.end(); @@ -2489,8 +2860,7 @@ cuobjdumpPTXSection* findPTXSectionInList(std::list<cuobjdumpSection*> sectionli if(ptxsection->getIdentifier() == identifier) return ptxsection; else { - extern bool g_cdp_enabled; - if(g_cdp_enabled) { + if(gpgpu_ctx->device_runtime->g_cdp_enabled) { printf("Warning: __cudaRegisterFatBinary needs %s, but find PTX section with %s\n", identifier.c_str(), ptxsection->getIdentifier().c_str()); return ptxsection; @@ -2502,7 +2872,7 @@ cuobjdumpPTXSection* findPTXSectionInList(std::list<cuobjdumpSection*> sectionli } //! Find an PTX section in all the known lists -cuobjdumpPTXSection* findPTXSection(const std::string identifier){ +cuobjdumpPTXSection* cuda_runtime_api::findPTXSection(const std::string identifier){ cuobjdumpPTXSection* sec = findPTXSectionInList(cuobjdumpSectionList, identifier); if (sec!=NULL)return sec; sec = findPTXSectionInList(libSectionList, identifier); @@ -2515,35 +2885,27 @@ cuobjdumpPTXSection* findPTXSection(const std::string identifier){ //! Extract the code using cuobjdump and remove unnecessary sections -void cuobjdumpInit(){ +void cuda_runtime_api::cuobjdumpInit(){ CUctx_st *context = GPGPUSim_Context(); extract_code_using_cuobjdump(); //extract all the output of cuobjdump to _cuobjdump_*.* const char* pre_load = getenv("CUOBJDUMP_SIM_FILE"); if (pre_load ==NULL || strlen(pre_load)==0){ - cuobjdumpSectionList = pruneSectionList(cuobjdumpSectionList, context); - cuobjdumpSectionList = mergeSections(cuobjdumpSectionList); + cuobjdumpSectionList = pruneSectionList(context); + cuobjdumpSectionList = mergeSections(); } } -std::map<int, std::string> fatbinmap; -std::map<int, bool>fatbin_registered; -std::map<std::string, symbol_table*> name_symtab; - -//! Keep track of the association between filename and cubin handle -void cuobjdumpRegisterFatBinary(unsigned int handle, const char* filename){ - fatbinmap[handle] = filename; -} //! Either submit PTX for simulation or convert SASS to PTXPlus and submit it -void cuobjdumpParseBinary(unsigned int handle){ +void gpgpu_context::cuobjdumpParseBinary(unsigned int handle){ - if(fatbin_registered[handle]) return; - fatbin_registered[handle] = true; CUctx_st *context = GPGPUSim_Context(); - std::string fname = fatbinmap[handle]; + if(api->fatbin_registered[handle]) return; + api->fatbin_registered[handle] = true; + std::string fname = api->fatbinmap[handle]; - if (name_symtab.find(fname) != name_symtab.end()) { - symbol_table *symtab = name_symtab[fname]; + if (api->name_symtab.find(fname) != api->name_symtab.end()) { + symbol_table *symtab = api->name_symtab[fname]; context->add_binary(symtab, handle); return; } @@ -2552,7 +2914,7 @@ void cuobjdumpParseBinary(unsigned int handle){ #if (CUDART_VERSION >= 6000) //loops through all ptx files from smallest sm version to largest std::map<unsigned,std::set<std::string> >::iterator itr_m; - for (itr_m = version_filename.begin(); itr_m!=version_filename.end(); itr_m++){ + for (itr_m = api->version_filename.begin(); itr_m!=api->version_filename.end(); itr_m++){ std::set<std::string>::iterator itr_s; for (itr_s = itr_m->second.begin(); itr_s!=itr_m->second.end(); itr_s++){ std::string ptx_filename = *itr_s; @@ -2560,11 +2922,11 @@ void cuobjdumpParseBinary(unsigned int handle){ symtab = gpgpu_ptx_sim_load_ptx_from_filename( ptx_filename.c_str() ); } } - name_symtab[fname] = symtab; + api->name_symtab[fname] = symtab; context->add_binary(symtab, handle); - load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); - load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); - for (itr_m = version_filename.begin(); itr_m!=version_filename.end(); itr_m++){ + api->load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); + api->load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); + for (itr_m = api->version_filename.begin(); itr_m!=api->version_filename.end(); itr_m++){ std::set<std::string>::iterator itr_s; for (itr_s = itr_m->second.begin(); itr_s!=itr_m->second.end(); itr_s++){ std::string ptx_filename = *itr_s; @@ -2576,8 +2938,8 @@ void cuobjdumpParseBinary(unsigned int handle){ #endif unsigned max_capability = 0; - for ( std::list<cuobjdumpSection*>::iterator iter = cuobjdumpSectionList.begin(); - iter != cuobjdumpSectionList.end(); + for ( std::list<cuobjdumpSection*>::iterator iter = api->cuobjdumpSectionList.begin(); + iter != api->cuobjdumpSectionList.end(); iter++){ unsigned capability = (*iter)->getArch(); if (capability > max_capability) max_capability = capability; @@ -2588,7 +2950,7 @@ void cuobjdumpParseBinary(unsigned int handle){ cuobjdumpPTXSection* ptx = NULL; const char* pre_load = getenv("CUOBJDUMP_SIM_FILE"); if(pre_load==NULL || strlen(pre_load)==0) - ptx = findPTXSection(fname); + ptx = api->findPTXSection(fname); char *ptxcode; const char *override_ptx_name = getenv("PTX_SIM_KERNELFILE"); if (override_ptx_name == NULL or getenv("PTX_SIM_USE_PTX_FILE") == NULL or strlen(getenv("PTX_SIM_USE_PTX_FILE"))==0) { @@ -2598,192 +2960,47 @@ void cuobjdumpParseBinary(unsigned int handle){ ptxcode = readfile(override_ptx_name); } if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) { - cuobjdumpELFSection* elfsection = findELFSection(ptx->getIdentifier()); + cuobjdumpELFSection* elfsection = api->findELFSection(ptx->getIdentifier()); assert (elfsection!= NULL); - char *ptxplus_str = gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus( + char *ptxplus_str = ptxinfo->gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus( ptx->getPTXfilename(), elfsection->getELFfilename(), elfsection->getSASSfilename()); symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxplus_str, handle); printf("Adding %s with cubin handle %u\n", ptx->getPTXfilename().c_str(), handle); context->add_binary(symtab, handle); - gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability ); + gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability, context->no_of_ptx ); delete[] ptxplus_str; } else { symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxcode, handle); //if CUOBJDUMP_SIM_FILE is not set, ptx is NULL. So comment below. //printf("Adding %s with cubin handle %u\n", ptx->getPTXfilename().c_str(), handle); context->add_binary(symtab, handle); - gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability ); + gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability, context->no_of_ptx ); } - load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); - load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); - name_symtab[fname] = symtab; + api->load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); + api->load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); + api->name_symtab[fname] = symtab; //TODO: Remove temporarily files as per configurations } +} + +extern "C" { void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin ) { if(g_debug_execution >= 3){ announce_call(__my_func__); } -#if (CUDART_VERSION < 2010) - printf("GPGPU-Sim PTX: ERROR ** this version of GPGPU-Sim requires CUDA 2.1 or higher\n"); - exit(1); -#endif - CUctx_st *context = GPGPUSim_Context(); - static unsigned next_fat_bin_handle = 1; - if(context->get_device()->get_gpgpu()->get_config().use_cuobjdump()) { - // The following workaround has only been verified on 64-bit systems. - if (sizeof(void*) == 4) - printf("GPGPU-Sim PTX: FatBin file name extraction has not been tested on 32-bit system.\n"); - - // This code will get the CUDA version the app was compiled with. - // We need this to determine how to handle the parsing of the binary. - // Making this a runtime variable based on the app, enables GPGPU-Sim compiled - // with a newer version of CUDA to run apps compiled with older versions of - // CUDA. This is especially useful for PTXPLUS execution. - //Skip cuda version check for pytorch application - std::string app_binary_path = get_app_binary(); - int pos = app_binary_path.find("python"); - if (pos==std::string::npos){ - // Not pytorch app : checking cuda version - int app_cuda_version = get_app_cuda_version(); - assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator." ); - } - - //int app_cuda_version = get_app_cuda_version(); - //assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator." ); - const char* filename; -#if CUDART_VERSION < 6000 - // FatBin handle from the .fatbin.c file (one of the intermediate files generated by NVCC) - typedef struct {int m; int v; const unsigned long long* d; char* f;} __fatDeviceText __attribute__ ((aligned (8))); - __fatDeviceText * fatDeviceText = (__fatDeviceText *) fatCubin; - - // Extract the source code file name that generate the given FatBin. - // - Obtains the pointer to the actual fatbin structure from the FatBin handle (fatCubin). - // - An integer inside the fatbin structure contains the relative offset to the source code file name. - // - This offset differs among different CUDA and GCC versions. - char * pfatbin = (char*) fatDeviceText->d; - int offset = *((int*)(pfatbin+48)); - filename = (pfatbin+16+offset); -#else - filename = "default"; -#endif - - // The extracted file name is associated with a fat_cubin_handle passed - // into cudaLaunch(). Inside cudaLaunch(), the associated file name is - // used to find the PTX/SASS section from cuobjdump, which contains the - // PTX/SASS code for the launched kernel function. - // This allows us to work around the fact that cuobjdump only outputs the - // file name associated with each section. - unsigned long long fat_cubin_handle = next_fat_bin_handle; - next_fat_bin_handle++; - printf("GPGPU-Sim PTX: __cudaRegisterFatBinary, fat_cubin_handle = %llu, filename=%s\n", fat_cubin_handle, filename); - /*! - * This function extracts all data from all files in first call - * then for next calls, only returns the appropriate number - */ - assert(fat_cubin_handle >= 1); - if (fat_cubin_handle==1) cuobjdumpInit(); - cuobjdumpRegisterFatBinary(fat_cubin_handle, filename); - - return (void**)fat_cubin_handle; - } -#if (CUDART_VERSION < 8000) - else { - static unsigned source_num=1; - unsigned long long fat_cubin_handle = next_fat_bin_handle++; - __cudaFatCudaBinary *info = (__cudaFatCudaBinary *)fatCubin; - assert( info->version >= 3 ); - unsigned num_ptx_versions=0; - unsigned max_capability=0; - unsigned selected_capability=0; - bool found=false; - unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_config().get_forced_max_capability(); - if (!info->ptx){ - printf("ERROR: Cannot find ptx code in cubin file\n" - "\tIf you are using CUDA 4.0 or higher, please enable -gpgpu_ptx_use_cuobjdump or downgrade to CUDA 3.1\n"); - exit(1); - } - while( info->ptx[num_ptx_versions].gpuProfileName != NULL ) { - unsigned capability=0; - sscanf(info->ptx[num_ptx_versions].gpuProfileName,"compute_%u",&capability); - printf("GPGPU-Sim PTX: __cudaRegisterFatBinary found PTX versions for '%s', ", info->ident); - printf("capability = %s\n", info->ptx[num_ptx_versions].gpuProfileName ); - if( forced_max_capability ) { - if( capability > max_capability && capability <= forced_max_capability ) { - found = true; - max_capability=capability; - selected_capability = num_ptx_versions; - } - } else { - if( capability > max_capability ) { - found = true; - max_capability=capability; - selected_capability = num_ptx_versions; - } - } - num_ptx_versions++; - } - if( found ) { - printf("GPGPU-Sim PTX: Loading PTX for %s, capability = %s\n", - info->ident, info->ptx[selected_capability].gpuProfileName ); - symbol_table *symtab; - const char *ptx = info->ptx[selected_capability].ptx; - if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) { - printf("GPGPU-Sim PTX: ERROR ** PTXPlus is only supported through cuobjdump\n" - "\tEither enable cuobjdump or disable PTXPlus in your configuration file\n"); - exit(1); - } else { - symtab=gpgpu_ptx_sim_load_ptx_from_string(ptx,source_num); - context->add_binary(symtab,fat_cubin_handle); - gpgpu_ptxinfo_load_from_string( ptx, source_num, max_capability ); - } - source_num++; - load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); - load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); - } else { - printf("GPGPU-Sim PTX: warning -- did not find an appropriate PTX in cubin\n"); - } - return (void**)fat_cubin_handle; - } -#else - else { - printf("ERROR ** __cudaRegisterFatBinary() needs to be updated\n"); - abort(); - } -#endif + return cudaRegisterFatBinaryInternal(fatCubin); } -void __cudaUnregisterFatBinary(void **fatCubinHandle) +void CUDARTAPI __cudaRegisterFatBinaryEnd( void **fatCubinHandle ) { if(g_debug_execution >= 3){ announce_call(__my_func__); } - ; -} - -cudaError_t cudaDeviceReset ( void ) { - // Should reset the simulated GPU - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - return g_last_cudaError = cudaSuccess; -} -cudaError_t CUDARTAPI cudaDeviceSynchronize(void){ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - //Blocks until the device has completed all preceding requested tasks - synchronize(); - return g_last_cudaError = cudaSuccess; -} - -void CUDARTAPI __cudaRegisterFatBinaryEnd( void **fatCubinHandle ) -{ - } unsigned CUDARTAPI __cudaPushCallConfiguration(dim3 gridDim, @@ -2791,7 +3008,10 @@ unsigned CUDARTAPI __cudaPushCallConfiguration(dim3 gridDim, size_t sharedMem = 0, struct CUstream_st *stream = 0) { - + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + cudaConfigureCallInternal(gridDim, blockDim, sharedMem, stream); } cudaError_t CUDARTAPI __cudaPopCallConfiguration( @@ -2801,9 +3021,13 @@ cudaError_t CUDARTAPI __cudaPopCallConfiguration( void *stream ) { + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } return g_last_cudaError = cudaSuccess; } + void CUDARTAPI __cudaRegisterFunction( void **fatCubinHandle, const char *hostFun, @@ -2814,18 +3038,19 @@ void CUDARTAPI __cudaRegisterFunction( uint3 *bid, dim3 *bDim, dim3 *gDim -) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - CUctx_st *context = GPGPUSim_Context(); - unsigned fat_cubin_handle = (unsigned)(unsigned long long)fatCubinHandle; - printf("GPGPU-Sim PTX: __cudaRegisterFunction %s : hostFun 0x%p, fat_cubin_handle = %u\n", - deviceFun, hostFun, fat_cubin_handle); - if(context->get_device()->get_gpgpu()->get_config().use_cuobjdump()) - cuobjdumpParseBinary(fat_cubin_handle); - context->register_function( fat_cubin_handle, hostFun, deviceFun ); +) { + cudaRegisterFunctionInternal( + fatCubinHandle, + hostFun, + deviceFun, + deviceName, + thread_limit, + tid, + bid, + bDim, + gDim + ); + } extern void __cudaRegisterVar( @@ -2838,19 +3063,43 @@ extern void __cudaRegisterVar( int constant, int global ) { + cudaRegisterVarInternal( + fatCubinHandle, + hostVar, + deviceAddress, + deviceName, + ext, + size, + constant, + global ); +} + +__host__ cudaError_t CUDARTAPI cudaConfigureCall(dim3 gridDim, dim3 blockDim, size_t sharedMem, cudaStream_t stream) +{ + return cudaConfigureCallInternal(gridDim, blockDim, sharedMem, stream); +} + +void __cudaUnregisterFatBinary(void **fatCubinHandle) +{ if(g_debug_execution >= 3){ announce_call(__my_func__); } - printf("GPGPU-Sim PTX: __cudaRegisterVar: hostVar = %p; deviceAddress = %s; deviceName = %s\n", hostVar, deviceAddress, deviceName); - printf("GPGPU-Sim PTX: __cudaRegisterVar: Registering const memory space of %d bytes\n", size); - if(GPGPUSim_Context()->get_device()->get_gpgpu()->get_config().use_cuobjdump()) - cuobjdumpParseBinary((unsigned)(unsigned long long)fatCubinHandle); - fflush(stdout); - if ( constant && !global && !ext ) { - gpgpu_ptx_sim_register_const_variable(hostVar,deviceName,size); - } else if ( !constant && !global && !ext ) { - gpgpu_ptx_sim_register_global_variable(hostVar,deviceName,size); - } else cuda_not_implemented(__my_func__,__LINE__); +} + +cudaError_t cudaDeviceReset ( void ) { + // Should reset the simulated GPU + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + return g_last_cudaError = cudaSuccess; +} +cudaError_t CUDARTAPI cudaDeviceSynchronize(void){ + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + //Blocks until the device has completed all preceding requested tasks + synchronize(); + return g_last_cudaError = cudaSuccess; } @@ -2922,10 +3171,6 @@ char __cudaInitModule( } -#ifndef OPENGL_SUPPORT -typedef unsigned long GLuint; -#endif - cudaError_t cudaGLRegisterBufferObject(GLuint bufferObj) { if(g_debug_execution >= 3){ @@ -2935,70 +3180,9 @@ cudaError_t cudaGLRegisterBufferObject(GLuint bufferObj) return g_last_cudaError = cudaSuccess; } -struct glbmap_entry { - GLuint m_bufferObj; - void *m_devPtr; - size_t m_size; - struct glbmap_entry *m_next; -}; -typedef struct glbmap_entry glbmap_entry_t; - -glbmap_entry_t* g_glbmap = NULL; - cudaError_t cudaGLMapBufferObject(void** devPtr, GLuint bufferObj) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } -#ifdef OPENGL_SUPPORT - GLint buffer_size=0; - CUctx_st* ctx = GPGPUSim_Context(); - - glbmap_entry_t *p = g_glbmap; - while ( p && p->m_bufferObj != bufferObj ) - p = p->m_next; - if ( p == NULL ) { - glBindBuffer(GL_ARRAY_BUFFER,bufferObj); - glGetBufferParameteriv(GL_ARRAY_BUFFER,GL_BUFFER_SIZE,&buffer_size); - assert( buffer_size != 0 ); - *devPtr = ctx->get_device()->get_gpgpu()->gpu_malloc(buffer_size); - - // create entry and insert to front of list - glbmap_entry_t *n = (glbmap_entry_t *) calloc(1,sizeof(glbmap_entry_t)); - n->m_next = g_glbmap; - g_glbmap = n; - - // initialize entry - n->m_bufferObj = bufferObj; - n->m_devPtr = *devPtr; - n->m_size = buffer_size; - - p = n; - } else { - buffer_size = p->m_size; - *devPtr = p->m_devPtr; - } - - if ( *devPtr ) { - char *data = (char *) calloc(p->m_size,1); - glGetBufferSubData(GL_ARRAY_BUFFER,0,buffer_size,data); - memcpy_to_gpu( (size_t) *devPtr, data, buffer_size ); - free(data); - printf("GPGPU-Sim PTX: cudaGLMapBufferObject %zu bytes starting at 0x%llx..\n", (size_t)buffer_size, - (unsigned long long) *devPtr); - return g_last_cudaError = cudaSuccess; - } else { - return g_last_cudaError = cudaErrorMemoryAllocation; - } - - return g_last_cudaError = cudaSuccess; -#else - fflush(stdout); - fflush(stderr); - printf("GPGPU-Sim PTX: GPGPU-Sim support for OpenGL integration disabled -- exiting\n"); - fflush(stdout); - exit(50); -#endif + return cudaGLMapBufferObjectInternal(devPtr, bufferObj); } cudaError_t cudaGLUnmapBufferObject(GLuint bufferObj) @@ -3007,7 +3191,8 @@ cudaError_t cudaGLUnmapBufferObject(GLuint bufferObj) announce_call(__my_func__); } #ifdef OPENGL_SUPPORT - glbmap_entry_t *p = g_glbmap; + CUctx_st* ctx = GPGPUSim_Context(); + glbmap_entry_t *p = ctx->api->g_glbmap; while ( p && p->m_bufferObj != bufferObj ) p = p->m_next; if ( p == NULL ) @@ -3041,45 +3226,12 @@ cudaError_t cudaGLUnregisterBufferObject(GLuint bufferObj) cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t bytes, unsigned int flags) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - *pHost = malloc(bytes); - //need to track the size allocated so that cudaHostGetDevicePointer() can function properly. - //TODO: vary this function behavior based on flags value (following nvidia documentation) - pinned_memory_size[*pHost]=bytes; - if( *pHost ) - return g_last_cudaError = cudaSuccess; - else - return g_last_cudaError = cudaErrorMemoryAllocation; + return cudaHostAllocInternal(pHost, bytes, flags); } cudaError_t CUDARTAPI cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - //only cpu memory allocation happens in cudaHostAlloc. Linking with device pointer to pinned memory happens here. - //TODO: once kernel is executed, the contents in global pointer of GPU must be copied back to CPU host pointer! - flags=0; - CUctx_st* context = GPGPUSim_Context(); - gpgpu_t *gpu = context->get_device()->get_gpgpu(); - std::map<void *, size_t>::const_iterator i = pinned_memory_size.find(pHost); - assert(i != pinned_memory_size.end()); - size_t size = i->second; - *pDevice = gpu->gpu_malloc(size); - if(g_debug_execution >= 3){ - printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n",size, (unsigned long long) *pDevice); - g_mallocPtr_Size[(unsigned long long)*pDevice] = size; - } - if ( *pDevice ) { - pinned_memory[pHost]=pDevice; - //Copy contents in cpu to gpu - gpu->memcpy_to_gpu((size_t)*pDevice,pHost,size); - return g_last_cudaError = cudaSuccess; - } else { - return g_last_cudaError = cudaErrorMemoryAllocation; - } + return cudaHostGetDevicePointerInternal(pDevice, pHost, flags); } __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( @@ -3143,61 +3295,12 @@ cudaError_t CUDARTAPI cudaSetDeviceFlags( int flags ) } } -size_t getMaxThreadsPerBlock(struct cudaFuncAttributes *attr) { - _cuda_device_id *dev = GPGPUSim_Init(); - struct cudaDeviceProp prop; - - prop = *dev->get_prop(); - - size_t max = prop.maxThreadsPerBlock; - - if (attr->numRegs && (prop.regsPerBlock / attr->numRegs) < max) - max = prop.regsPerBlock / attr->numRegs; - if (attr->sharedSizeBytes && (prop.sharedMemPerBlock / attr->sharedSizeBytes) < max) - max = prop.sharedMemPerBlock / attr->sharedSizeBytes; - return max; -} cudaError_t CUDARTAPI cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const char *hostFun ) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - CUctx_st *context = GPGPUSim_Context(); - function_info *entry = context->get_kernel(hostFun); - if( entry ) { - const struct gpgpu_ptx_sim_info *kinfo = entry->get_kernel_info(); - attr->sharedSizeBytes = kinfo->smem; - attr->constSizeBytes = kinfo->cmem; - attr->localSizeBytes = kinfo->lmem; - attr->numRegs = kinfo->regs; - if(kinfo->maxthreads > 0) - attr->maxThreadsPerBlock = kinfo->maxthreads; - else - attr->maxThreadsPerBlock = getMaxThreadsPerBlock(attr); -#if CUDART_VERSION >= 3000 - attr->ptxVersion = kinfo->ptx_version; - attr->binaryVersion = kinfo->sm_target; -#endif - } - return g_last_cudaError = cudaSuccess; -} - -cudaError_t CUDARTAPI cudaEventCreateWithFlags(cudaEvent_t *event, int flags) -{ - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - CUevent_st *e = new CUevent_st(flags==cudaEventBlockingSync); - g_timer_events[e->get_uid()] = e; -#if CUDART_VERSION >= 3000 - *event = e; -#else - *event = e->get_uid(); -#endif - return g_last_cudaError = cudaSuccess; + return cudaFuncGetAttributesInternal(attr, hostFun ); } cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) @@ -3237,26 +3340,64 @@ __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, size_t v return g_last_cudaError = cudaSuccess; } -#if CUDART_VERSION >= 9000 -__host__ cudaError_t cudaFuncSetAttribute ( const void* func, enum cudaFuncAttribute attr, int value ) { +//#if CUDART_VERSION >= 9000 +//__host__ cudaError_t cudaFuncSetAttribute ( const void* func, enum cudaFuncAttribute attr, int value ) { //ignore this Attribute for now, and the default is that carveout = cudaSharedmemCarveoutDefault; // (-1) - return g_last_cudaError = cudaSuccess; -} +// return g_last_cudaError = cudaSuccess; +//} -#if CUDART_VERSION >= 9020 -__host__ __device__ unsigned __cudaPushCallConfiguration(dim3 gridDim, dim3 blockDim, - size_t sharedMem = 0, - void *stream = 0) { - return 1; -} #endif #endif #endif + +#if CUDART_VERSION >= 9000 +/** + * \brief Set attributes for a given function + * + * This function sets the attributes of a function specified via \p entry. + * The parameter \p entry must be a pointer to a function that executes + * on the device. The parameter specified by \p entry must be declared as a \p __global__ + * function. The enumeration defined by \p attr is set to the value defined by \p value + * If the specified function does not exist, then ::cudaErrorInvalidDeviceFunction is returned. + * If the specified attribute cannot be written, or if the value is incorrect, + * then ::cudaErrorInvalidValue is returned. + * + * Valid values for \p attr are: + * ::cuFuncAttrMaxDynamicSharedMem - Maximum size of dynamic shared memory per block + * ::cudaFuncAttributePreferredSharedMemoryCarveout - Preferred shared memory-L1 cache split ratio + * + * \param entry - Function to get attributes of + * \param attr - Attribute to set + * \param value - Value to set + * + * \return + * ::cudaSuccess, + * ::cudaErrorInitializationError, + * ::cudaErrorInvalidDeviceFunction, + * ::cudaErrorInvalidValue + * \notefnerr + * + * \ref ::cudaLaunchKernel(const T *func, dim3 gridDim, dim3 blockDim, void **args, size_t sharedMem, cudaStream_t stream) "cudaLaunchKernel (C++ API)", + * \ref ::cudaFuncSetCacheConfig(T*, enum cudaFuncCache) "cudaFuncSetCacheConfig (C++ API)", + * \ref ::cudaFuncGetAttributes(struct cudaFuncAttributes*, const void*) "cudaFuncGetAttributes (C API)", + * ::cudaSetDoubleForDevice, + * ::cudaSetDoubleForHost, + * \ref ::cudaSetupArgument(T, size_t) "cudaSetupArgument (C++ API)" + */ +cudaError_t CUDARTAPI cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) +{ + if(g_debug_execution >= 3){ + announce_call(__my_func__); + } + printf("GPGPU-Sim PTX: Execution warning: ignoring call to \"%s ( func=%p, attr=%d, value=%d )\"\n", + __my_func__, func, attr, value ); + return g_last_cudaError = cudaSuccess; +} #endif cudaError_t CUDARTAPI cudaGLSetGLDevice(int device) @@ -3328,17 +3469,9 @@ int CUDARTAPI __cudaSynchronizeThreads(void**, void*) //////// -extern int ptx_parse(); -extern int ptx__scan_string(const char*); -extern FILE *ptx_in; - -extern int ptxinfo_parse(); -extern int ptxinfo_debug; -extern FILE *ptxinfo_in; - /// static functions -static int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr, gpgpu_t *gpu ) +int cuda_runtime_api::load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr, gpgpu_t *gpu ) { if(g_debug_execution >= 3){ announce_call(__my_func__); @@ -3377,7 +3510,7 @@ static int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsign return ng_bytes; } -static int load_constants( symbol_table *symtab, addr_t min_gaddr, gpgpu_t *gpu ) +int cuda_runtime_api::load_constants( symbol_table *symtab, addr_t min_gaddr, gpgpu_t *gpu ) { if(g_debug_execution >= 3){ announce_call(__my_func__); @@ -3423,7 +3556,7 @@ static int load_constants( symbol_table *symtab, addr_t min_gaddr, gpgpu_t *gpu return nc_bytes; } -kernel_info_t *gpgpu_cuda_ptx_sim_init_grid( const char *hostFun, +kernel_info_t * cuda_runtime_api::gpgpu_cuda_ptx_sim_init_grid( const char *hostFun, gpgpu_ptx_sim_arg_list_t args, struct dim3 gridDim, struct dim3 blockDim, @@ -3451,7 +3584,7 @@ kernel_info_t *gpgpu_cuda_ptx_sim_init_grid( const char *hostFun, } entry->finalize(result->get_param_memory()); - g_ptx_kernel_count++; + gpgpu_ctx->func_sim->g_ptx_kernel_count++; fflush(stdout); if(g_debug_execution >= 4){ @@ -3919,33 +4052,8 @@ CUresult CUDAAPI cuLinkAddFile(CUlinkState state, CUjitInputType type, const char *path, unsigned int numOptions, CUjit_option *options, void **optionValues) { - if(g_debug_execution >= 3){ - announce_call(__my_func__); - } - static bool addedFile = false; - if (addedFile){ - printf("GPGPU-Sim PTX: ERROR: cuLinkAddFile does not support multiple files\n"); - abort(); - } - - //blocking - assert(type==CU_JIT_INPUT_PTX); - CUctx_st *context = GPGPUSim_Context(); - char *file = getenv("PTX_JIT_PATH"); - if(file==NULL){ - printf("GPGPU-Sim PTX: ERROR: PTX_JIT_PATH has not been set\n"); - abort(); - } - strcat(file,"/"); - strcat(file,path); - symbol_table *symtab = gpgpu_ptx_sim_load_ptx_from_filename( file ); - std::string fname(path); - name_symtab[fname] = symtab; - context->add_binary(symtab, 1); - load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); - load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); - addedFile = true; - return CUDA_SUCCESS; + return cuLinkAddFileInternal(state, type, path, + numOptions, options, optionValues); } #endif @@ -4939,12 +5047,12 @@ CUresult CUDAAPI cuLaunchKernel(CUfunction f, const char *hostFun = (const char*) f; CUctx_st *context = GPGPUSim_Context(); function_info *entry = context->get_kernel(hostFun); - cudaConfigureCall(dim3(gridDimX, gridDimY, gridDimZ), dim3(blockDimX, blockDimY, blockDimZ), sharedMemBytes, (cudaStream_t) hStream); + cudaConfigureCallInternal(dim3(gridDimX, gridDimY, gridDimZ), dim3(blockDimX, blockDimY, blockDimZ), sharedMemBytes, (cudaStream_t) hStream); for(unsigned i = 0; i < entry->num_args(); i++){ std::pair<size_t, unsigned> p = entry->get_param_config(i); cudaSetupArgument(kernelParams[i], p.first, p.second); } - cudaLaunch(hostFun); + cudaLaunchInternal(hostFun); return CUDA_SUCCESS; } #endif /* CUDART_VERSION >= 4000 */ diff --git a/libcuda/cuobjdump.h b/libcuda/cuobjdump.h new file mode 100644 index 0000000..6ab6778 --- /dev/null +++ b/libcuda/cuobjdump.h @@ -0,0 +1,80 @@ +#ifndef __cuobjdump_h__ +#define __cuobjdump_h__ +#include <string> +#include <list> +#include <iostream> + +typedef void * yyscan_t; +struct cuobjdump_parser { + yyscan_t scanner; + int elfserial; + int ptxserial; + FILE *ptxfile; + FILE *elffile; + FILE *sassfile; + char filename [1024]; +}; + +class cuobjdumpSection { +public: + //Constructor + cuobjdumpSection() { + arch = 0; + identifier = ""; + } + virtual ~cuobjdumpSection() {} + unsigned getArch() {return arch;} + void setArch(unsigned a) {arch = a;} + std::string getIdentifier() {return identifier;} + void setIdentifier(std::string i) {identifier = i;} + virtual void print(){std::cout << "cuobjdump Section: unknown type" << std::endl;} +private: + unsigned arch; + std::string identifier; +}; + +class cuobjdumpELFSection : public cuobjdumpSection +{ +public: + cuobjdumpELFSection() {} + virtual ~cuobjdumpELFSection() { + elffilename = ""; + sassfilename = ""; + } + std::string getELFfilename() {return elffilename;} + void setELFfilename(std::string f) {elffilename = f;} + std::string getSASSfilename() {return sassfilename;} + void setSASSfilename(std::string f) {sassfilename = f;} + virtual void print() { + std::cout << "ELF Section:" << std::endl; + std::cout << "arch: sm_" << getArch() << std::endl; + std::cout << "identifier: " << getIdentifier() << std::endl; + std::cout << "elf filename: " << getELFfilename() << std::endl; + std::cout << "sass filename: " << getSASSfilename() << std::endl; + std::cout << std::endl; + } +private: + std::string elffilename; + std::string sassfilename; +}; + +class cuobjdumpPTXSection : public cuobjdumpSection +{ +public: + cuobjdumpPTXSection(){ + ptxfilename = ""; + } + std::string getPTXfilename() {return ptxfilename;} + void setPTXfilename(std::string f) {ptxfilename = f;} + virtual void print() { + std::cout << "PTX Section:" << std::endl; + std::cout << "arch: sm_" << getArch() << std::endl; + std::cout << "identifier: " << getIdentifier() << std::endl; + std::cout << "ptx filename: " << getPTXfilename() << std::endl; + std::cout << std::endl; + } +private: + std::string ptxfilename; +}; + +#endif /* __cuobjdump_h__ */ diff --git a/libcuda/cuobjdump.l b/libcuda/cuobjdump.l index 2b0dac8..5a19d65 100644 --- a/libcuda/cuobjdump.l +++ b/libcuda/cuobjdump.l @@ -30,6 +30,7 @@ %{ #include <stdio.h> #include <string.h> +#include "cuobjdump.h" #include "cuobjdump_parser.h" #define YY_NEVER_INTERACTIVE 1 @@ -38,9 +39,9 @@ #define YYDEBUG 1 -#define yylval cuobjdump_lval - -void cuobjdump_error(const char*); +void cuobjdump_error(yyscan_t yyscanner, struct cuobjdump_parser* parser, std::list<cuobjdumpSection*> &cuobjdumpSectionList, const char* msg); +#define YY_DECL int cuobjdump_lex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner, struct cuobjdump_parser* parser, std::list<cuobjdumpSection*> &cuobjdumpSectionList) %} %option stack @@ -48,6 +49,8 @@ void cuobjdump_error(const char*); %option yylineno %option nounput +%option bison-bridge +%option reentrant %s ptxcode %s sasscode @@ -69,54 +72,54 @@ newlines {newline}+ "ptxasOptions"{notnewline}*{newline} -[1-9]{numeric}* yylval.string_value = strdup(yytext); return DECIMAL; +[1-9]{numeric}* yylval->string_value = strdup(yytext); return DECIMAL; "has debug info"{newline} "Fatbin ptx code:"{newline} { - yy_push_state(ptxcode); - yy_push_state(identifier); - yy_push_state(ptxheader); - yylval.string_value = strdup(yytext); + yy_push_state(ptxcode, yyscanner); + yy_push_state(identifier, yyscanner); + yy_push_state(ptxheader, yyscanner); + yylval->string_value = strdup(yytext); return PTXHEADER; } "Fatbin elf code:"{newline} { - yy_push_state(elfcode); - yy_push_state(identifier); - yy_push_state(elfheader); - yylval.string_value = strdup(yytext); + yy_push_state(elfcode, yyscanner); + yy_push_state(identifier, yyscanner); + yy_push_state(elfheader, yyscanner); + yylval->string_value = strdup(yytext); return ELFHEADER; } /*PTX code tokens*/ -<ptxcode>{notnewline}*{newline} yylval.string_value = strdup(yytext); return PTXLINE; +<ptxcode>{notnewline}*{newline} yylval->string_value = strdup(yytext); return PTXLINE; /*ELF code tokens*/ <elfcode>{whitespace}*"code for sm_"{numeric}+{newline} { BEGIN(sasscode); - yylval.string_value = strdup(yytext); + yylval->string_value = strdup(yytext); return SASSLINE; } -<elfcode>{notnewline}*{newline} yylval.string_value = strdup(yytext); return ELFLINE; +<elfcode>{notnewline}*{newline} yylval->string_value = strdup(yytext); return ELFLINE; /*SASS code tokens*/ -<sasscode>{notnewline}*{newline} yylval.string_value = strdup(yytext); return SASSLINE; +<sasscode>{notnewline}*{newline} yylval->string_value = strdup(yytext); return SASSLINE; <identifier>{newline}"compressed"{newline} BEGIN(conidentifier); return H_COMPRESSED; <identifier>{newline}"identifier = " BEGIN(endidentifier); return H_IDENTIFIER; -<identifier>{newline}{newline} yy_pop_state(); +<identifier>{newline}{newline} yy_pop_state(yyscanner); <conidentifier>"identifier = " BEGIN(endidentifier); return H_IDENTIFIER; -<conidentifier>{newline} yy_pop_state(); +<conidentifier>{newline} yy_pop_state(yyscanner); -<endidentifier>{notnewline}+ yylval.string_value = strdup(yytext); yy_pop_state(); return FILENAME; +<endidentifier>{notnewline}+ yylval->string_value = strdup(yytext); yy_pop_state(yyscanner); return FILENAME; /*Header tokens*/ -<elfheader>[[:alnum:]_]+ yylval.string_value = strdup(yytext); return IDENTIFIER; +<elfheader>[[:alnum:]_]+ yylval->string_value = strdup(yytext); return IDENTIFIER; <elfheader>"================" return H_SEPARATOR; <elfheader>"arch = " return H_ARCH; <elfheader>"code version = " return H_CODEVERSION; @@ -128,7 +131,7 @@ newlines {newline}+ /*Header tokens*/ -<ptxheader>[[:alnum:]_]+ yylval.string_value = strdup(yytext); return IDENTIFIER; +<ptxheader>[[:alnum:]_]+ yylval->string_value = strdup(yytext); return IDENTIFIER; <ptxheader>"================" return H_SEPARATOR; <ptxheader>"arch = " return H_ARCH; <ptxheader>"code version = " return H_CODEVERSION; @@ -143,7 +146,7 @@ newlines {newline}+ /* Looking for the identifier (filename) then the header is done */ -<endheader>{notnewline}+ yylval.string_value = strdup(yytext); yy_pop_state(); return IDENTIFIER; +<endheader>{notnewline}+ yylval->string_value = strdup(yytext); yy_pop_state(yyscanner); return IDENTIFIER; @@ -153,11 +156,12 @@ newlines {newline}+ <<EOF>> BEGIN(INITIAL);return 0; /*No other rule matched. Throw an error*/ -. cuobjdump_error("Invalid token"); +. cuobjdump_error(yyscanner, parser, cuobjdumpSectionList, "Invalid token"); %% -void cuobjdump_error(const char* message) +void cuobjdump_error(yyscan_t yyscanner, struct cuobjdump_parser* parser, std::list<cuobjdumpSection*> &cuobjdumpSectionList, const char* msg) { - printf(" %s near \"%s\"",message, yytext); - printf(" on line %i\n",yylineno); + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + printf(" %s near \"%s\"",msg, yytext); + printf(" on line %i\n",yylineno); } diff --git a/libcuda/cuobjdump.y b/libcuda/cuobjdump.y index 31760f7..8d1bca6 100644 --- a/libcuda/cuobjdump.y +++ b/libcuda/cuobjdump.y @@ -29,24 +29,31 @@ %{ #include <stdio.h> -int yylex(void); -void yyerror(const char*); -extern void addCuobjdumpSection(int sectiontype); -void setCuobjdumparch(const char* arch); -void setCuobjdumpidentifier(const char* identifier); -void setCuobjdumpptxfilename(const char* filename); -void setCuobjdumpelffilename(const char* filename); -void setCuobjdumpsassfilename(const char* filename); -int elfserial = 1; -int ptxserial = 1; -FILE *ptxfile; -FILE *elffile; -FILE *sassfile; -char filename [1024]; +typedef void * yyscan_t; +#include "cuobjdump.h" + +extern void addCuobjdumpSection(int sectiontype, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +void setCuobjdumparch(const char* arch, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +void setCuobjdumpidentifier(const char* identifier, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +void setCuobjdumpptxfilename(const char* filename, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +void setCuobjdumpelffilename(const char* filename, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +void setCuobjdumpsassfilename(const char* filename, std::list<cuobjdumpSection*> &cuobjdumpSectionList); %} +%define api.pure full +%parse-param {yyscan_t scanner} +%parse-param {struct cuobjdump_parser* parser} +%parse-param {std::list<cuobjdumpSection*> &cuobjdumpSectionList} +%lex-param {yyscan_t scanner} +%lex-param {struct cuobjdump_parser* parser} +%lex-param {std::list<cuobjdumpSection*> &cuobjdumpSectionList} + %union { char* string_value; } +%{ +int yylex(YYSTYPE * yylval_param, yyscan_t yyscanner, struct cuobjdump_parser* parser, std::list<cuobjdumpSection*> &cuobjdumpSectionList); +void yyerror(yyscan_t yyscanner, struct cuobjdump_parser* parser, std::list<cuobjdumpSection*> &cuobjdumpSectionList, const char* msg); +%} %token <string_value> H_SEPARATOR H_ARCH H_CODEVERSION H_PRODUCER H_HOST H_COMPILESIZE H_IDENTIFIER H_UNKNOWN H_COMPRESSED %token <string_value> CODEVERSION %token <string_value> STRING @@ -70,25 +77,25 @@ emptylines : emptylines NEWLINE | ; section : PTXHEADER { - addCuobjdumpSection(0); - snprintf(filename, 1024, "_cuobjdump_%d.ptx", ptxserial++); - ptxfile = fopen(filename, "w"); - setCuobjdumpptxfilename(filename); + addCuobjdumpSection(0, cuobjdumpSectionList); + snprintf(parser->filename, 1024, "_cuobjdump_%d.ptx", parser->ptxserial++); + parser->ptxfile = fopen(parser->filename, "w"); + setCuobjdumpptxfilename(parser->filename, cuobjdumpSectionList); } headerinfo compressedkeyword identifier ptxcode { - fclose(ptxfile); + fclose(parser->ptxfile); } | ELFHEADER { - addCuobjdumpSection(1); - snprintf(filename, 1024, "_cuobjdump_%d.elf", elfserial); - elffile = fopen(filename, "w"); - setCuobjdumpelffilename(filename); + addCuobjdumpSection(1, cuobjdumpSectionList); + snprintf(parser->filename, 1024, "_cuobjdump_%d.elf", parser->elfserial); + parser->elffile = fopen(parser->filename, "w"); + setCuobjdumpelffilename(parser->filename, cuobjdumpSectionList); } headerinfo compressedkeyword identifier elfcode { - fclose(elffile); - snprintf(filename, 1024, "_cuobjdump_%d.sass", elfserial++); - sassfile = fopen(filename, "w"); - setCuobjdumpsassfilename(filename); + fclose(parser->elffile); + snprintf(parser->filename, 1024, "_cuobjdump_%d.sass", parser->elfserial++); + parser->sassfile = fopen(parser->filename, "w"); + setCuobjdumpsassfilename(parser->filename, cuobjdumpSectionList); } sasscode { - fclose(sassfile); + fclose(parser->sassfile); }; headerinfo : H_SEPARATOR NEWLINE @@ -96,27 +103,27 @@ headerinfo : H_SEPARATOR NEWLINE H_CODEVERSION CODEVERSION NEWLINE H_PRODUCER H_UNKNOWN NEWLINE H_HOST IDENTIFIER NEWLINE - H_COMPILESIZE IDENTIFIER {setCuobjdumparch($4);}; + H_COMPILESIZE IDENTIFIER {setCuobjdumparch($4, cuobjdumpSectionList);}; | H_SEPARATOR NEWLINE H_ARCH IDENTIFIER NEWLINE H_CODEVERSION CODEVERSION NEWLINE H_PRODUCER IDENTIFIER NEWLINE H_HOST IDENTIFIER NEWLINE - H_COMPILESIZE IDENTIFIER {setCuobjdumparch($4);}; + H_COMPILESIZE IDENTIFIER {setCuobjdumparch($4, cuobjdumpSectionList);}; -identifier : H_IDENTIFIER FILENAME emptylines {setCuobjdumpidentifier($2);} - | {setCuobjdumpidentifier("default");}; +identifier : H_IDENTIFIER FILENAME emptylines {setCuobjdumpidentifier($2, cuobjdumpSectionList);} + | {setCuobjdumpidentifier("default", cuobjdumpSectionList);}; compressedkeyword : H_COMPRESSED emptylines | ; -ptxcode : ptxcode PTXLINE {fprintf(ptxfile, "%s", $2);} +ptxcode : ptxcode PTXLINE {fprintf(parser->ptxfile, "%s", $2);} | ; -elfcode : elfcode ELFLINE {fprintf(elffile, "%s", $2);} +elfcode : elfcode ELFLINE {fprintf(parser->elffile, "%s", $2);} | ; -sasscode : sasscode SASSLINE {fprintf(sassfile, "%s", $2);} +sasscode : sasscode SASSLINE {fprintf(parser->sassfile, "%s", $2);} | ; diff --git a/libcuda/gpgpu_context.h b/libcuda/gpgpu_context.h new file mode 100644 index 0000000..45c5cdd --- /dev/null +++ b/libcuda/gpgpu_context.h @@ -0,0 +1,71 @@ +#ifndef __gpgpu_context_h__ +#define __gpgpu_context_h__ +#include "cuda_api_object.h" +#include "../src/cuda-sim/ptx_loader.h" +#include "../src/cuda-sim/ptx_parser.h" +#include "../src/gpgpusim_entrypoint.h" +#include "../src/cuda-sim/cuda-sim.h" +#include "../src/cuda-sim/cuda_device_runtime.h" +#include "../src/cuda-sim/ptx-stats.h" + +class gpgpu_context { + public: + gpgpu_context() { + g_global_allfiles_symbol_table = NULL; + sm_next_access_uid=0; + warp_inst_sm_next_uid=0; + operand_info_sm_next_uid = 1; + kernel_info_m_next_uid = 1; + g_num_ptx_inst_uid = 0; + g_ptx_cta_info_uid = 1; + symbol_sm_next_uid = 1; + function_info_sm_next_uid = 1; + debug_tensorcore = 0; + api = new cuda_runtime_api(this); + ptxinfo = new ptxinfo_data(this); + ptx_parser = new ptx_recognizer(this); + the_gpgpusim = new GPGPUsim_ctx(this); + func_sim = new cuda_sim(this); + device_runtime = new cuda_device_runtime(this); + stats = new ptx_stats(this); + } + // global list + symbol_table *g_global_allfiles_symbol_table; + const char *g_filename; + unsigned sm_next_access_uid; + unsigned warp_inst_sm_next_uid; + unsigned operand_info_sm_next_uid;//uid for operand_info + unsigned kernel_info_m_next_uid;//uid for kernel_info_t + unsigned g_num_ptx_inst_uid; //uid for ptx inst inside ptx_instruction + unsigned long long g_ptx_cta_info_uid; + unsigned symbol_sm_next_uid; //uid for symbol + unsigned function_info_sm_next_uid; + std::vector<ptx_instruction*> s_g_pc_to_insn; // a direct mapping from PC to instruction + bool debug_tensorcore; + + // objects pointers for each file + cuda_runtime_api* api; + ptxinfo_data* ptxinfo; + ptx_recognizer* ptx_parser; + GPGPUsim_ctx* the_gpgpusim; + cuda_sim* func_sim; + cuda_device_runtime* device_runtime; + ptx_stats* stats; + // member function list + void cuobjdumpParseBinary(unsigned int handle); + class symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ); + class symbol_table *gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ); + void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_version); + void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version=20, int no_of_ptx=0 ); + void print_ptx_file( const char *p, unsigned source_num, const char *filename ); + class symbol_table* init_parser(const char*); + class gpgpu_sim *gpgpu_ptx_sim_init_perf(); + struct _cuda_device_id *GPGPUSim_Init(); + void ptx_reg_options(option_parser_t opp); + const ptx_instruction* pc_to_instruction(unsigned pc); + const warp_inst_t *ptx_fetch_inst( address_type pc ); + unsigned translate_pc_to_ptxlineno(unsigned pc); +}; +gpgpu_context* GPGPU_Context(); + +#endif /* __gpgpu_context_h__ */ diff --git a/libopencl/opencl_runtime_api.cc b/libopencl/opencl_runtime_api.cc index 97a54d8..7f029c7 100644 --- a/libopencl/opencl_runtime_api.cc +++ b/libopencl/opencl_runtime_api.cc @@ -84,6 +84,7 @@ #include "../src/gpgpusim_entrypoint.h" #include "../src/gpgpu-sim/gpu-sim.h" #include "../src/gpgpu-sim/shader.h" +#include "../libcuda/gpgpu_context.h" //# define __my_func__ __PRETTY_FUNCTION__ # if defined __cplusplus ? __GNUC_PREREQ (2, 6) : __GNUC_PREREQ (2, 4) @@ -424,6 +425,8 @@ void register_ptx_function( const char *name, function_info *impl ) void _cl_program::Build(const char *options) { + gpgpu_context *ctx; + ctx = GPGPU_Context(); printf("GPGPU-Sim OpenCL API: compiling OpenCL kernels...\n"); std::map<cl_uint,pgm_info>::iterator i; for( i = m_pgm.begin(); i!= m_pgm.end(); i++ ) { @@ -534,7 +537,7 @@ void _cl_program::Build(const char *options) exit(1); } } - if( !g_keep_intermediate_files ) { + if( !ctx->ptxinfo->g_keep_intermediate_files ) { // clean up files... snprintf(commandline,1024,"rm -f %s", cl_fname ); int result = system(commandline); @@ -576,8 +579,8 @@ void _cl_program::Build(const char *options) } } info.m_asm = tmp; - info.m_symtab = gpgpu_ptx_sim_load_ptx_from_string( tmp, source_num ); - gpgpu_ptxinfo_load_from_string( tmp, source_num ); + info.m_symtab = ctx->gpgpu_ptx_sim_load_ptx_from_string( tmp, source_num ); + ctx->gpgpu_ptxinfo_load_from_string( tmp, source_num ); free(tmp); } printf("GPGPU-Sim OpenCL API: finished compiling OpenCL kernels.\n"); @@ -645,7 +648,9 @@ class _cl_device_id *GPGPUSim_Init() { static _cl_device_id *the_device = NULL; if( !the_device ) { - gpgpu_sim *the_gpu = gpgpu_ptx_sim_init_perf(); + gpgpu_context *ctx; + ctx = GPGPU_Context(); + gpgpu_sim *the_gpu = ctx->gpgpu_ptx_sim_init_perf(); the_device = new _cl_device_id(the_gpu); } start_sim_thread(2); @@ -872,14 +877,16 @@ clEnqueueNDRangeKernel(cl_command_queue command_queue, const cl_event * event_wait_list, cl_event * event) CL_API_SUFFIX__VERSION_1_0 { + gpgpu_context *ctx; + ctx = GPGPU_Context(); int _global_size[3]; int zeros[3] = { 0, 0, 0}; printf("\n\n\n"); char *mode = getenv("PTX_SIM_MODE_FUNC"); if ( mode ) - sscanf(mode,"%u", &g_ptx_sim_mode); + sscanf(mode,"%u", &(ctx->func_sim->g_ptx_sim_mode)); printf("GPGPU-Sim OpenCL API: clEnqueueNDRangeKernel '%s' (mode=%s)\n", kernel->name().c_str(), - g_ptx_sim_mode?"functional simulation":"performance simulation"); + (ctx->func_sim->g_ptx_sim_mode)?"functional simulation":"performance simulation"); if ( !work_dim || work_dim > 3 ) return CL_INVALID_WORK_DIMENSION; size_t _local_size[3]; if( local_work_size != NULL ) { @@ -943,15 +950,15 @@ clEnqueueNDRangeKernel(cl_command_queue command_queue, gpgpu_t *gpu = command_queue->get_device()->the_device(); if (kernel->get_implementation()->get_ptx_version().ver() <3.0){ - gpgpu_ptx_sim_memcpy_symbol( "%_global_size", _global_size, 3 * sizeof(int), 0, 1, gpu ); - gpgpu_ptx_sim_memcpy_symbol( "%_work_dim", &work_dim, 1 * sizeof(int), 0, 1, gpu ); - gpgpu_ptx_sim_memcpy_symbol( "%_global_num_groups", &GridDim, 3 * sizeof(int), 0, 1, gpu ); - gpgpu_ptx_sim_memcpy_symbol( "%_global_launch_offset", zeros, 3 * sizeof(int), 0, 1, gpu ); - gpgpu_ptx_sim_memcpy_symbol( "%_global_block_offset", zeros, 3 * sizeof(int), 0, 1, gpu ); + ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( "%_global_size", _global_size, 3 * sizeof(int), 0, 1, gpu ); + ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( "%_work_dim", &work_dim, 1 * sizeof(int), 0, 1, gpu ); + ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( "%_global_num_groups", &GridDim, 3 * sizeof(int), 0, 1, gpu ); + ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( "%_global_launch_offset", zeros, 3 * sizeof(int), 0, 1, gpu ); + ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( "%_global_block_offset", zeros, 3 * sizeof(int), 0, 1, gpu ); } - kernel_info_t *grid = gpgpu_opencl_ptx_sim_init_grid(kernel->get_implementation(),params,GridDim,BlockDim,gpu); - if ( g_ptx_sim_mode ) - gpgpu_opencl_ptx_sim_main_func( grid ); + kernel_info_t *grid = ctx->func_sim->gpgpu_opencl_ptx_sim_init_grid(kernel->get_implementation(),params,GridDim,BlockDim,gpu); + if ( ctx->func_sim->g_ptx_sim_mode ) + ctx->func_sim->gpgpu_opencl_ptx_sim_main_func( grid ); else gpgpu_opencl_ptx_sim_main_perf( grid ); return CL_SUCCESS; diff --git a/nightly.jenkinsfile b/nightly.jenkinsfile index 5221b3b..e5ffa57 100644 --- a/nightly.jenkinsfile +++ b/nightly.jenkinsfile @@ -22,10 +22,12 @@ pipeline { } stage('nightly-simulations-build'){ steps{ + sh 'if [ -d "./gpgpu-sim_simulations" ]; then \ + cp -fr ./gpgpu-sim_simulations ./gpgpu-sim_simulations_bak; \ + fi' sh 'rm -rf gpgpu-sim_simulations' - sh 'git clone [email protected]:TimRogersGroup/gpgpu-sim_simulations.git && \ + sh 'git clone [email protected]:purdue-aalp/gpgpu-sim_simulations.git && \ cd gpgpu-sim_simulations && \ - git checkout purdue-cluster && \ git pull && \ ln -s /home/tgrogers-raid/a/common/data_dirs benchmarks/' sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ @@ -38,30 +40,64 @@ pipeline { } stage('nightly-2B-insn-run'){ steps { + sh 'rm -rf ./gpgpu-sim_simulations/util/plotting/correl-html && rm -rf gpgpu-sim-results-repo &&\ + rm -rf ./gpgpu-sim_simulations/util/plotting/htmls' + sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ - source `pwd`/setup_environment &&\ - ./gpgpu-sim_simulations/util/job_launching/run_simulations.py -B `cat ./gpgpu-sim_simulations/util/job_launching/apps/all-apps.list` -C TITANX-2B,TITANX-L1ON-2B,P100-2B,TITANV-2B -N nightly-$$ && \ - PLOTDIR="jenkins/${JOB_NAME}/${BUILD_NUMBER}/getstats" && ssh [email protected] mkdir -p /home/dynamo/a/tgrogers/website/gpgpu-sim-plots/$PLOTDIR && \ - ./gpgpu-sim_simulations/util/job_launching/monitor_func_test.py -I -S 1800 -v -s stats-$$.csv -N nightly-$$ && \ - ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c stats-$$.csv -p [email protected]:~/website/gpgpu-sim-plots/$PLOTDIR -w https://engineering.purdue.edu/tgrogers/gpgpu-sim-plots/$PLOTDIR -n $PLOTDIR' + source `pwd`/setup_environment &&\ + ./gpgpu-sim_simulations/util/job_launching/run_simulations.py \ + -B `cat ./gpgpu-sim_simulations/util/job_launching/apps/all-apps.list` -C TITANV-2B -N nightly-$$ && \ + ./gpgpu-sim_simulations/util/job_launching/monitor_func_test.py -I -S 1800 -v \ + -s stats-per-app-9.1.csv -T 12 -K -N nightly-$$ && \ + ./gpgpu-sim_simulations/util/plotting/plot-get-stats.py -c stats-per-app-9.1.csv -P cuda-9.1.nightly' } } stage('nightly-correlate'){ steps { + sh 'git clone [email protected]:purdue-aalp/gpgpu-sim-results-repo.git' + + sh 'if [ ! -d ./gpgpu-sim-results-repo/${JOB_NAME} ]; then \ + mkdir -p ./gpgpu-sim-results-repo/${JOB_NAME}/ ; \ + cp ./gpgpu-sim-results-repo/purdue-aalp/gpgpu-sim_distribution/dev/* \ + ./gpgpu-sim-results-repo/${JOB_NAME}/ ; \ + fi && \ + ./gpgpu-sim_simulations/run_hw/get_hw_data.sh' + sh 'source /home/tgrogers-raid/a/common/gpgpu-sim-setup/9.1_env_setup.sh &&\ + ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k \ + -B `cat ./gpgpu-sim_simulations/util/job_launching/apps/all-apps.list` \ + -C TITANV-2B > stats-per-kernel-9.1.csv &&\ + ./gpgpu-sim_simulations/util/plotting/merge-stats.py \ + -c ./gpgpu-sim-results-repo/${JOB_NAME}/stats-per-app-9.1.csv,./stats-per-app-9.1.csv -R \ + > per-app-merge-9.1.csv &&\ + ./gpgpu-sim_simulations/util/plotting/merge-stats.py \ + -c ./gpgpu-sim-results-repo/${JOB_NAME}/stats-per-kernel-9.1.csv,./stats-per-kernel-9.1.csv -R \ + > per-kernel-merge-9.1.csv &&\ source `pwd`/setup_environment &&\ - PLOTDIR="jenkins/${JOB_NAME}" &&\ - ./gpgpu-sim_simulations/util/job_launching/get_stats.py -R -K -k -B `cat ./gpgpu-sim_simulations/util/job_launching/apps/all-apps.list` -C TITANX-2B,TITANX-L1ON-2B,P100-2B,TITANV-2B > nightly-stats-per-kernel-9.1.csv &&\ - ./gpgpu-sim_simulations/util/plotting/correlate_and_publish.sh nightly-stats-per-kernel-9.1.csv $PLOTDIR ${BUILD_NUMBER}' + ./gpgpu-sim_simulations/util/plotting/plot-correlation.py -c per-kernel-merge-9.1.csv \ + -p cuda-9.1.nightly -b ./gpgpu-sim_simulations/util/plotting/known.correlation.outliers.list \ + | grep "Correl=" | tee correl.9.1.txt &&\ + cp stats-per-*.csv ./gpgpu-sim-results-repo/${JOB_NAME}/ &&\ + cd ./gpgpu-sim-results-repo &&\ + git pull &&\ + git diff --quiet && git diff --staged --quiet || git commit -am "Jenkins automated checkin ${JOB_NAME} Build:${BUILD_NUMBER}" &&\ + git push' + + sh 'PLOTDIR="/home/dynamo/a/tgrogers/website/gpgpu-sim-plots/jenkins/${JOB_NAME}" &&\ + ssh [email protected] mkdir -p $PLOTDIR/${BUILD_NUMBER} && \ + scp ./gpgpu-sim_simulations/util/plotting/correl-html/* [email protected]:$PLOTDIR/${BUILD_NUMBER} &&\ + scp ./gpgpu-sim_simulations/util/plotting/htmls/* [email protected]:$PLOTDIR/${BUILD_NUMBER} &&\ + ssh [email protected] "cd $PLOTDIR && rm -rf latest && cp -r ${BUILD_NUMBER} latest"' } } } post { success { - emailext body: "See ${BUILD_URL}", + emailext body:'''${SCRIPT, template="groovy-html.nightly.success.template"}''', recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], subject: "[AALP Jenkins] Build #${BUILD_NUMBER} - Success!", + attachmentsPattern: 'correl.*.txt', to: '[email protected]' } failure { diff --git a/setup_environment b/setup_environment index 17891ce..58f4713 100644 --- a/setup_environment +++ b/setup_environment @@ -148,19 +148,15 @@ fi echo ""; echo "----------------------------------------------------------------------------"; echo "INFO - If you only care about PTX execution, ignore this message. GPGPU-Sim supports PTX execution in modern CUDA." -if [ $CUDA_VERSION_NUMBER -gt 4200 ]; then - echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration, the apps and simulator must be compiled with CUDA 4.2." - echo "You can still run a PASCAL configuration when compiling with 4.2 by setting the \$PTXAS_CUDA_INSTALL_PATH directory environment variable." -else - echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration - set the envronment variable" - echo "\$PTXAS_CUDA_INSTALL_PATH to point a CUDA version compabible with your card configurations (i.e. 8+ for PASCAL, 9+ for VOLTA etc..)" - echo "For example: \"export \$PTXAS_CUDA_INSTALL_PATH=/usr/local/cuda-9.1\"" -fi +echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration - set the envronment variable" +echo "\$PTXAS_CUDA_INSTALL_PATH to point a CUDA version compabible with your card configurations (i.e. 8+ for PASCAL, 9+ for VOLTA etc..)" +echo "For example: \"export \$PTXAS_CUDA_INSTALL_PATH=/usr/local/cuda-9.1\"" +echo "" echo "The following text describes why:"; echo "If you are using PTXPLUS, only sm_1x is supported and it requires that the app and simulator binaries are compiled in CUDA 4.2 or less."; echo "The simulator requires it since CUDA headers desribe struct sizes in the exec which change from gen to gen."; echo "The apps require 4.2 because new versions of CUDA tools have dropped parsing support for generating sm_1x"; -echo "When running using modern config (i.e. pascal) and PTXPLUS with CUDA 4.2, the \$PTXAS_CUDA_INSTALL_PATH env variable is required to get proper register usage" +echo "When running using modern config (i.e. volta) and PTXPLUS with CUDA 4.2, the \$PTXAS_CUDA_INSTALL_PATH env variable is required to get proper register usage" echo "(and hence occupancy) using a version of CUDA that knows the register usage on the real card." echo ""; echo "----------------------------------------------------------------------------"; diff --git a/src/Makefile b/src/Makefile index 6001669..3ad511e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -51,6 +51,8 @@ else CXXFLAGS += endif +CXXFLAGS += -I$(CUDA_INSTALL_PATH)/include + OPTFLAGS += -g3 -fPIC CPP = g++ $(SNOW) diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 023f51b..9a91818 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -34,13 +34,33 @@ #include "cuda-sim/cuda-sim.h" #include "gpgpu-sim/gpu-sim.h" #include "option_parser.h" +#include "gpgpusim_entrypoint.h" #include <algorithm> #include <sys/stat.h> #include <sstream> #include <iostream> +#include "../libcuda/gpgpu_context.h" -unsigned mem_access_t::sm_next_access_uid = 0; -unsigned warp_inst_t::sm_next_uid = 0; +void mem_access_t::init(gpgpu_context* ctx) +{ + gpgpu_ctx = ctx; + m_uid=++(gpgpu_ctx->sm_next_access_uid); + m_addr=0; + m_req_size=0; +} +void warp_inst_t::issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id, int sch_id ) +{ + m_warp_active_mask = mask; + m_warp_issued_mask = mask; + m_uid = ++(m_config->gpgpu_ctx->warp_inst_sm_next_uid); + m_warp_id = warp_id; + m_dynamic_warp_id = dynamic_warp_id; + issue_cycle = cycle; + cycles = initiation_interval; + m_cache_hit=false; + m_empty=false; + m_scheduler_id=sch_id; +} checkpoint::checkpoint() { @@ -172,9 +192,10 @@ void gpgpu_functional_sim_config::ptx_set_tex_cache_linesize(unsigned linesize) m_texcache_linesize = linesize; } -gpgpu_t::gpgpu_t( const gpgpu_functional_sim_config &config ) +gpgpu_t::gpgpu_t( const gpgpu_functional_sim_config &config, gpgpu_context* ctx ) : m_function_model_config(config) { + gpgpu_ctx = ctx; m_global_mem = new memory_space_impl<8192>("global",64*1024); m_tex_mem = new memory_space_impl<8192>("tex",64*1024); @@ -198,6 +219,9 @@ gpgpu_t::gpgpu_t( const gpgpu_functional_sim_config &config ) if(m_function_model_config.get_ptx_inst_debug_to_file() != 0) ptx_inst_debug_file = fopen(m_function_model_config.get_ptx_inst_debug_file(), "w"); + + gpu_sim_cycle=0; + gpu_tot_sim_cycle=0; } address_type line_size_based_tag_func(new_addr_type address, new_addr_type line_size) @@ -402,7 +426,7 @@ void warp_inst_t::generate_mem_accesses() } assert( total_accesses > 0 && total_accesses <= m_config->warp_size ); cycles = total_accesses; // shared memory conflicts modeled as larger initiation interval - ptx_file_line_stats_add_smem_bank_conflict( pc, total_accesses ); + m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_smem_bank_conflict( pc, total_accesses ); break; } @@ -443,11 +467,11 @@ void warp_inst_t::generate_mem_accesses() byte_mask.set(idx+i); } for( a=accesses.begin(); a != accesses.end(); ++a ) - m_accessq.push_back( mem_access_t(access_type,a->first,cache_block_size,is_write,a->second, byte_mask, mem_access_sector_mask_t())); + m_accessq.push_back( mem_access_t(access_type,a->first,cache_block_size,is_write,a->second, byte_mask, mem_access_sector_mask_t(), m_config->gpgpu_ctx)); } if ( space.get_type() == global_space ) { - ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); + m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); } m_mem_accesses_created=true; } @@ -675,21 +699,16 @@ void warp_inst_t::memory_coalescing_arch_reduce_and_send( bool is_write, mem_acc assert(lower_half_used && upper_half_used); } } - m_accessq.push_back( mem_access_t(access_type,addr,size,is_write,info.active,info.bytes, info.chunks) ); + m_accessq.push_back( mem_access_t(access_type,addr,size,is_write,info.active,info.bytes, info.chunks,m_config->gpgpu_ctx) ); } void warp_inst_t::completed( unsigned long long cycle ) const { unsigned long long latency = cycle - issue_cycle; assert(latency <= cycle); // underflow detection - ptx_file_line_stats_add_latency(pc, latency * active_count()); + m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count()); } -//Jin: CDP support -bool g_cdp_enabled; -unsigned g_kernel_launch_latency; - -unsigned kernel_info_t::m_next_uid = 1; kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry) { @@ -701,14 +720,14 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info * m_next_cta.z=0; m_next_tid=m_next_cta; m_num_cores_running=0; - m_uid = m_next_uid++; + m_uid = (entry->gpgpu_ctx->kernel_info_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; //Jin: launch latency management - m_launch_latency = g_kernel_launch_latency; + m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency; volta_cache_config_set=false; } @@ -726,14 +745,14 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info * m_next_cta.z=0; m_next_tid=m_next_cta; m_num_cores_running=0; - m_uid = m_next_uid++; + m_uid = (entry->gpgpu_ctx->kernel_info_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; //Jin: launch latency management - m_launch_latency = g_kernel_launch_latency; + m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency; volta_cache_config_set=false; m_NameToCudaArray = nameToCudaArray; @@ -787,17 +806,16 @@ bool kernel_info_t::children_all_finished() { void kernel_info_t::notify_parent_finished() { if(m_parent_kernel) { - extern unsigned long long g_total_param_size; - g_total_param_size -= ((m_kernel_entry->get_args_aligned_size() + 255)/256*256); + m_kernel_entry->gpgpu_ctx->device_runtime->g_total_param_size -= ((m_kernel_entry->get_args_aligned_size() + 255)/256*256); m_parent_kernel->remove_child(this); - g_stream_manager->register_finished_kernel(m_parent_kernel->get_uid()); + 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); + 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); @@ -813,7 +831,7 @@ CUstream_st * kernel_info_t::get_default_stream_cta(dim3 ctaid) { else { m_cta_streams[ctaid] = std::list<CUstream_st *>(); CUstream_st * stream = new CUstream_st(); - g_stream_manager->add_stream(stream); + g_stream_manager()->add_stream(stream); m_cta_streams[ctaid].push_back(stream); return stream; } @@ -845,17 +863,18 @@ void kernel_info_t::destroy_cta_streams() { for(auto s = m_cta_streams.begin(); s != m_cta_streams.end(); s++) { stream_size += s->second.size(); for(auto ss = s->second.begin(); ss != s->second.end(); ss++) - g_stream_manager->destroy_stream(*ss); + g_stream_manager()->destroy_stream(*ss); s->second.clear(); } printf("size %lu\n", stream_size); m_cta_streams.clear(); } -simt_stack::simt_stack( unsigned wid, unsigned warpSize) +simt_stack::simt_stack( unsigned wid, unsigned warpSize, class gpgpu_sim * gpu) { m_warp_id=wid; m_warp_size = warpSize; + m_gpu=gpu; reset(); } @@ -961,7 +980,7 @@ void simt_stack::print (FILE *fout) const } else { fprintf(fout," " ); } - ptx_print_insn( stack_entry.m_pc, fout ); + m_gpu->gpgpu_ctx->func_sim->ptx_print_insn( stack_entry.m_pc, fout ); fprintf(fout,"\n"); } @@ -1055,7 +1074,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre simt_stack_entry new_stack_entry; new_stack_entry.m_pc = tmp_next_pc; new_stack_entry.m_active_mask = tmp_active_mask; - new_stack_entry.m_branch_div_cycle = gpu_sim_cycle+gpu_tot_sim_cycle; + new_stack_entry.m_branch_div_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle; new_stack_entry.m_type = STACK_ENTRY_TYPE_CALL; m_stack.push_back(new_stack_entry); return; @@ -1087,7 +1106,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre new_recvg_pc = recvg_pc; if (new_recvg_pc != top_recvg_pc) { m_stack.back().m_pc = new_recvg_pc; - m_stack.back().m_branch_div_cycle = gpu_sim_cycle+gpu_tot_sim_cycle; + m_stack.back().m_branch_div_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle; m_stack.push_back(simt_stack_entry()); } @@ -1113,7 +1132,7 @@ void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, addre if (warp_diverged) { - ptx_file_line_stats_add_warp_divergence(top_pc, 1); + m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_warp_divergence(top_pc, 1); } } @@ -1160,7 +1179,7 @@ warp_inst_t core_t::getExecuteWarp(unsigned warpId) { unsigned pc,rpc; m_simt_stack[warpId]->get_pdom_stack_top_info(&pc,&rpc); - warp_inst_t wi= *ptx_fetch_inst(pc); + warp_inst_t wi= *(m_gpu->gpgpu_ctx->ptx_fetch_inst(pc)); wi.set_active(m_simt_stack[warpId]->get_active_mask()); return wi; } @@ -1179,7 +1198,7 @@ void core_t::initilizeSIMTStack(unsigned warp_count, unsigned warp_size) { m_simt_stack = new simt_stack*[warp_count]; for (unsigned i = 0; i < warp_count; ++i) - m_simt_stack[i] = new simt_stack(i,warp_size); + m_simt_stack[i] = new simt_stack(i,warp_size,m_gpu); m_warp_size = warp_size; m_warp_count = warp_count; } diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 27a1ba6..8c19e33 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -31,6 +31,8 @@ // Forward declarations class gpgpu_sim; class kernel_info_t; +class gpgpu_context; + //Set a hard limit of 32 CTAs per shader [cuda only has 8] #define MAX_CTA_PER_SHADER 32 @@ -173,9 +175,7 @@ enum _memory_op_t { #include <algorithm> #if !defined(__VECTOR_TYPES_H__) -struct dim3 { - unsigned int x, y, z; -}; +#include "vector_types.h" #endif struct dim3comp { bool operator() (const dim3 & a, const dim3 & b) const @@ -197,7 +197,7 @@ void increment_x_then_y_then_z( dim3 &i, const dim3 &bound); #include "stream_manager.h" class stream_manager; struct CUstream_st; -extern stream_manager * g_stream_manager; +//extern stream_manager * g_stream_manager; //support for pinned memories added extern std::map<void *,void **> pinned_memory; extern std::map<void *, size_t> pinned_memory_size; @@ -300,7 +300,6 @@ private: class function_info *m_kernel_entry; unsigned m_uid; - static unsigned m_next_uid; //These maps contain the snapshot of the texture mappings at kernel launch std::map<std::string, const struct cudaArray*> m_NameToCudaArray; @@ -348,9 +347,11 @@ public: mutable bool volta_cache_config_set; }; -struct core_config { - core_config() - { +class core_config { + public: + core_config(gpgpu_context* ctx) + { + gpgpu_ctx = ctx; m_valid = false; num_shmem_bank=16; shmem_limited_broadcast = false; @@ -362,6 +363,8 @@ struct core_config { bool m_valid; unsigned warp_size; + // backward pointer + class gpgpu_context* gpgpu_ctx; // off-chip memory request architecture parameters int gpgpu_coalesce_arch; @@ -400,7 +403,7 @@ typedef std::vector<address_type> addr_vector_t; class simt_stack { public: - simt_stack( unsigned wid, unsigned warpSize); + simt_stack( unsigned wid, unsigned warpSize, class gpgpu_sim * gpu); void reset(); void launch( address_type start_pc, const simt_mask_t &active_mask ); @@ -417,6 +420,7 @@ protected: unsigned m_warp_id; unsigned m_warp_size; + enum stack_entry_type { STACK_ENTRY_TYPE_NORMAL = 0, STACK_ENTRY_TYPE_CALL @@ -434,6 +438,8 @@ protected: }; std::deque<simt_stack_entry> m_stack; + + class gpgpu_sim * m_gpu; }; #define GLOBAL_HEAP_START 0xC0000000 @@ -452,19 +458,7 @@ protected: #if !defined(__CUDA_RUNTIME_API_H__) -enum cudaChannelFormatKind { - cudaChannelFormatKindSigned, - cudaChannelFormatKindUnsigned, - cudaChannelFormatKindFloat -}; - -struct cudaChannelFormatDesc { - int x; - int y; - int z; - int w; - enum cudaChannelFormatKind f; -}; +#include "builtin_types.h" struct cudaArray { void *devPtr; @@ -476,28 +470,6 @@ struct cudaArray { unsigned dimensions; }; -enum cudaTextureAddressMode { - cudaAddressModeWrap, - cudaAddressModeClamp -}; - -enum cudaTextureFilterMode { - cudaFilterModePoint, - cudaFilterModeLinear -}; - -enum cudaTextureReadMode { - cudaReadModeElementType, - cudaReadModeNormalizedFloat -}; - -struct textureReference { - int normalized; - enum cudaTextureFilterMode filterMode; - enum cudaTextureAddressMode addressMode[3]; - struct cudaChannelFormatDesc channelDesc; -}; - #endif // Struct that record other attributes in the textureReference declaration @@ -563,7 +535,9 @@ private: class gpgpu_t { public: - gpgpu_t( const gpgpu_functional_sim_config &config ); + gpgpu_t( const gpgpu_functional_sim_config &config, gpgpu_context* ctx ); + // backward pointer + class gpgpu_context* gpgpu_ctx; int checkpoint_option; int checkpoint_kernel; int checkpoint_CTA; @@ -572,6 +546,12 @@ public: int resume_CTA; int checkpoint_CTA_t; int checkpoint_insn_Y; + + //Move some cycle core stats here instead of being global + unsigned long long gpu_sim_cycle; + unsigned long long gpu_tot_sim_cycle; + + void* gpu_malloc( size_t size ); void* gpu_mallocarray( size_t count ); void gpu_memset( size_t dst_start_addr, int c, size_t count ); @@ -752,13 +732,14 @@ enum cache_operator_type { class mem_access_t { public: - mem_access_t() { init(); } + mem_access_t(gpgpu_context* ctx) { init(ctx); } mem_access_t( mem_access_type type, new_addr_type address, unsigned size, - bool wr ) + bool wr, + gpgpu_context* ctx) { - init(); + init(ctx); m_type = type; m_addr = address; m_req_size = size; @@ -770,10 +751,11 @@ public: bool wr, const active_mask_t &active_mask, const mem_access_byte_mask_t &byte_mask, - const mem_access_sector_mask_t §or_mask) + const mem_access_sector_mask_t §or_mask, + gpgpu_context* ctx) : m_warp_mask(active_mask), m_byte_mask(byte_mask), m_sector_mask(sector_mask) { - init(); + init(ctx); m_type = type; m_addr = address; m_req_size = size; @@ -806,13 +788,9 @@ public: } } + gpgpu_context* gpgpu_ctx; private: - void init() - { - m_uid=++sm_next_access_uid; - m_addr=0; - m_req_size=0; - } + void init(gpgpu_context* ctx); unsigned m_uid; new_addr_type m_addr; // request address @@ -822,8 +800,6 @@ private: active_mask_t m_warp_mask; mem_access_byte_mask_t m_byte_mask; mem_access_sector_mask_t m_sector_mask; - - static unsigned sm_next_access_uid; }; class mem_fetch; @@ -836,8 +812,8 @@ public: class mem_fetch_allocator { public: - virtual mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const = 0; - virtual mem_fetch *alloc( const class warp_inst_t &inst, const mem_access_t &access ) const = 0; + virtual mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const = 0; + virtual mem_fetch *alloc( const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle ) const = 0; }; // the maximum number of destination, source, or address uarch operands in a instruction @@ -958,7 +934,7 @@ public: m_empty=true; m_config=NULL; } - warp_inst_t( const core_config *config ) + warp_inst_t( const core_config *config ) { m_uid=0; assert(config->warp_size<=MAX_WARP_SIZE); @@ -982,19 +958,9 @@ public: { m_empty=true; } - void issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id, int sch_id ) - { - m_warp_active_mask = mask; - m_warp_issued_mask = mask; - m_uid = ++sm_next_uid; - m_warp_id = warp_id; - m_dynamic_warp_id = dynamic_warp_id; - issue_cycle = cycle; - cycles = initiation_interval; - m_cache_hit=false; - m_empty=false; - m_scheduler_id=sch_id; - } + + void issue( const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id, int sch_id ); + const active_mask_t & get_active_mask() const { return m_warp_active_mask; @@ -1129,7 +1095,6 @@ public: unsigned get_uid() const { return m_uid; } unsigned get_schd_id() const { return m_scheduler_id; } - protected: unsigned m_uid; @@ -1158,8 +1123,6 @@ protected: bool m_mem_accesses_created; std::list<mem_access_t> m_accessq; - static unsigned sm_next_uid; - unsigned m_scheduler_id; //the scheduler that issues this inst //Jin: cdp support diff --git a/src/cuda-sim/Makefile b/src/cuda-sim/Makefile index 999dad7..85d1c8c 100644 --- a/src/cuda-sim/Makefile +++ b/src/cuda-sim/Makefile @@ -79,16 +79,16 @@ libgpgpu_ptx_sim.a: $(OBJS) ar rcs $(OUTPUT_DIR)/libgpgpu_ptx_sim.a $(OUTPUT_DIR)/ptx.tab.o $(OUTPUT_DIR)/lex.ptx_.o $(OUTPUT_DIR)/ptxinfo.tab.o $(OUTPUT_DIR)/lex.ptxinfo_.o $(OBJS) $(OUTPUT_DIR)/ptx.tab.o: $(OUTPUT_DIR)/ptx.tab.c - $(CPP) -c $(OPT) -DYYDEBUG $(OUTPUT_DIR)/ptx.tab.c -o $(OUTPUT_DIR)/ptx.tab.o + $(CPP) -c $(CXX_OPT) -DYYDEBUG $(OUTPUT_DIR)/ptx.tab.c -o $(OUTPUT_DIR)/ptx.tab.o $(OUTPUT_DIR)/lex.ptx_.o: $(OUTPUT_DIR)/lex.ptx_.c - $(CPP) -c $(OPT) $(OUTPUT_DIR)/lex.ptx_.c -o $(OUTPUT_DIR)/lex.ptx_.o + $(CPP) -c $(CXX_OPT) $(OUTPUT_DIR)/lex.ptx_.c -o $(OUTPUT_DIR)/lex.ptx_.o $(OUTPUT_DIR)/ptxinfo.tab.o: $(OUTPUT_DIR)/ptxinfo.tab.c - $(CPP) -c $(OPT) -DYYDEBUG $(OUTPUT_DIR)/ptxinfo.tab.c -o $(OUTPUT_DIR)/ptxinfo.tab.o + $(CPP) -c $(CXX_OPT) -DYYDEBUG $(OUTPUT_DIR)/ptxinfo.tab.c -o $(OUTPUT_DIR)/ptxinfo.tab.o $(OUTPUT_DIR)/lex.ptxinfo_.o: $(OUTPUT_DIR)/lex.ptxinfo_.c $(OUTPUT_DIR)/ptxinfo.tab.c - $(CPP) -c $(OPT) $(OUTPUT_DIR)/lex.ptxinfo_.c -o $(OUTPUT_DIR)/lex.ptxinfo_.o + $(CPP) -c $(CXX_OPT) $(OUTPUT_DIR)/lex.ptxinfo_.c -o $(OUTPUT_DIR)/lex.ptxinfo_.o $(OUTPUT_DIR)/ptx.tab.c: ptx.y bison --name-prefix=ptx_ -v -d ptx.y --file-prefix=$(OUTPUT_DIR)/ptx diff --git a/src/cuda-sim/cuda-math.h b/src/cuda-sim/cuda-math.h index a5db337..9a5468c 100644 --- a/src/cuda-sim/cuda-math.h +++ b/src/cuda-sim/cuda-math.h @@ -277,10 +277,10 @@ int float2int(float a, enum cudaRoundMode mode) { int tmp; switch (mode) { - case cuda_math::cudaRoundZero: tmp = truncf(a); break; - case cuda_math::cudaRoundNearest: tmp = nearbyintf(a); break; - case cuda_math::cudaRoundMinInf: tmp = floorf(a); break; - case cuda_math::cudaRoundPosInf: tmp = ceilf(a); break; + case cudaRoundZero: tmp = truncf(a); break; + case cudaRoundNearest: tmp = nearbyintf(a); break; + case cudaRoundMinInf: tmp = floorf(a); break; + case cudaRoundPosInf: tmp = ceilf(a); break; default: abort(); } return tmp; @@ -296,10 +296,10 @@ unsigned int float2uint(float a, enum cudaRoundMode mode) { unsigned int tmp; switch (mode) { - case cuda_math::cudaRoundZero: tmp = truncf(a); break; - case cuda_math::cudaRoundNearest: tmp = nearbyintf(a); break; - case cuda_math::cudaRoundMinInf: tmp = floorf(a); break; - case cuda_math::cudaRoundPosInf: tmp = ceilf(a); break; + case cudaRoundZero: tmp = truncf(a); break; + case cudaRoundNearest: tmp = nearbyintf(a); break; + case cudaRoundMinInf: tmp = floorf(a); break; + case cudaRoundPosInf: tmp = ceilf(a); break; default: abort(); } return tmp; diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 4c0fc58..1b0e841 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -30,6 +30,8 @@ #include "instructions.h" #include "ptx_ir.h" +class ptx_recognizer; +typedef void * yyscan_t; #include "ptx.tab.h" #include "ptx_sim.h" #include <stdio.h> @@ -49,27 +51,13 @@ #include "decuda_pred_table/decuda_pred_table.h" #include "../stream_manager.h" #include "cuda_device_runtime.h" +#include "../../libcuda/gpgpu_context.h" -int gpgpu_ptx_instruction_classification; -void ** g_inst_classification_stat = NULL; -void ** g_inst_op_classification_stat= NULL; -int g_ptx_kernel_count = -1; // used for classification stat collection purposes int g_debug_execution = 0; -int g_debug_thread_uid = 0; -addr_t g_debug_pc = 0xBEEF1518; // Output debug information to file options -int cp_count; -int cp_cta_resume; -unsigned g_ptx_sim_num_insn = 0; -unsigned gpgpu_param_num_shaders = 0; -char *opcode_latency_int, *opcode_latency_fp, *opcode_latency_dp,*opcode_latency_sfu,*opcode_latency_tensor; -char *opcode_initiation_int, *opcode_initiation_fp, *opcode_initiation_dp,*opcode_initiation_sfu,*opcode_initiation_tensor; -char *cdp_latency_str; -unsigned cdp_latency[5]; - -void ptx_opcocde_latency_options (option_parser_t opp) { +void cuda_sim::ptx_opcocde_latency_options (option_parser_t opp) { option_parser_register(opp, "-ptx_opcode_latency_int", OPT_CSTR, &opcode_latency_int, "Opcode latencies for integers <ADD,MAX,MUL,MAD,DIV>" "Default 1,1,19,25,145", @@ -118,8 +106,6 @@ cudaLaunchDeviceV2_init_perWarp, cudaLaunchDevicV2_perKernel>" "7200,8000,100,12000,1600"); } -static address_type get_converge_point(address_type pc); - void gpgpu_t::gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref, int dim, int readmode, int ext) { std::string texname(name); @@ -229,10 +215,6 @@ void gpgpu_t::gpgpu_ptx_sim_unbindTexture(const struct textureReference* texref) m_NameToTextureInfo.erase(texname); } -unsigned g_assemble_code_next_pc=0; -std::map<unsigned,function_info*> g_pc_to_finfo; -std::vector<ptx_instruction*> function_info::s_g_pc_to_insn; - #define MAX_INST_SIZE 8 /*bytes*/ void function_info::ptx_assemble() @@ -250,39 +232,39 @@ void function_info::ptx_assemble() fflush(stdout); std::list<ptx_instruction*>::iterator i; - addr_t PC = g_assemble_code_next_pc; // globally unique address (across functions) + addr_t PC = gpgpu_ctx->func_sim->g_assemble_code_next_pc; // globally unique address (across functions) // start function on an aligned address for( unsigned i=0; i < (PC%MAX_INST_SIZE); i++ ) - s_g_pc_to_insn.push_back((ptx_instruction*)NULL); + gpgpu_ctx->s_g_pc_to_insn.push_back((ptx_instruction*)NULL); PC += PC%MAX_INST_SIZE; m_start_PC = PC; addr_t n=0; // offset in m_instr_mem //Why s_g_pc_to_insn.size() is needed to reserve additional memory for insts? reserve is cumulative. //s_g_pc_to_insn.reserve(s_g_pc_to_insn.size() + MAX_INST_SIZE*m_instructions.size()); - s_g_pc_to_insn.reserve(MAX_INST_SIZE*m_instructions.size()); + gpgpu_ctx->s_g_pc_to_insn.reserve(MAX_INST_SIZE*m_instructions.size()); for ( i=m_instructions.begin(); i != m_instructions.end(); i++ ) { ptx_instruction *pI = *i; if ( pI->is_label() ) { const symbol *l = pI->get_label(); labels[l->name()] = n; } else { - g_pc_to_finfo[PC] = this; + gpgpu_ctx->func_sim->g_pc_to_finfo[PC] = this; m_instr_mem[n] = pI; - s_g_pc_to_insn.push_back(pI); - assert(pI == s_g_pc_to_insn[PC]); + gpgpu_ctx->s_g_pc_to_insn.push_back(pI); + assert(pI == gpgpu_ctx->s_g_pc_to_insn[PC]); pI->set_m_instr_mem_index(n); pI->set_PC(PC); assert( pI->inst_size() <= MAX_INST_SIZE ); for( unsigned i=1; i < pI->inst_size(); i++ ) { - s_g_pc_to_insn.push_back((ptx_instruction*)NULL); + gpgpu_ctx->s_g_pc_to_insn.push_back((ptx_instruction*)NULL); m_instr_mem[n+i]=NULL; } n += pI->inst_size(); PC += pI->inst_size(); } } - g_assemble_code_next_pc=PC; + gpgpu_ctx->func_sim->g_assemble_code_next_pc=PC; for ( unsigned ii=0; ii < n; ii += m_instr_mem[ii]->inst_size() ) { // handle branch instructions ptx_instruction *pI = m_instr_mem[ii]; if ( pI->get_opcode() == BRA_OP || pI->get_opcode() == BREAKADDR_OP || pI->get_opcode() == CALLP_OP) { @@ -446,8 +428,8 @@ void gpgpu_t::memcpy_to_gpu( size_t dst_start_addr, const void *src, size_t coun m_global_mem->write(dst_start_addr+n,1, src_data+n,NULL,NULL); // Copy into the performance model. - extern gpgpu_sim* g_the_gpu; - g_the_gpu->perf_memcpy_to_gpu(dst_start_addr, count); + //extern gpgpu_sim* g_the_gpu; + g_the_gpu()->perf_memcpy_to_gpu(dst_start_addr, count); if(g_debug_execution >= 3) { printf( " done.\n"); fflush(stdout); @@ -465,8 +447,8 @@ void gpgpu_t::memcpy_from_gpu( void *dst, size_t src_start_addr, size_t count ) m_global_mem->read(src_start_addr+n,1,dst_data+n); // Copy into the performance model. - extern gpgpu_sim* g_the_gpu; - g_the_gpu->perf_memcpy_to_gpu(src_start_addr, count); + //extern gpgpu_sim* g_the_gpu; + g_the_gpu()->perf_memcpy_to_gpu(src_start_addr, count); if(g_debug_execution >= 3) { printf( " done.\n"); fflush(stdout); @@ -507,7 +489,7 @@ void gpgpu_t::gpu_memset( size_t dst_start_addr, int c, size_t count ) } } -void ptx_print_insn( address_type pc, FILE *fp ) +void cuda_sim::ptx_print_insn( address_type pc, FILE *fp ) { std::map<unsigned,function_info*>::iterator f = g_pc_to_finfo.find(pc); if( f == g_pc_to_finfo.end() ) { @@ -519,7 +501,7 @@ void ptx_print_insn( address_type pc, FILE *fp ) finfo->print_insn(pc,fp); } -std::string ptx_get_insn_str( address_type pc ) +std::string cuda_sim::ptx_get_insn_str( address_type pc ) { std::map<unsigned,function_info*>::iterator f = g_pc_to_finfo.find(pc); if( f == g_pc_to_finfo.end() ) { @@ -665,35 +647,38 @@ void ptx_instruction::set_opcode_and_latency() * [3] MAD * [4] DIV */ - sscanf(opcode_latency_int, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_int, "%u,%u,%u,%u,%u", &int_latency[0],&int_latency[1],&int_latency[2], &int_latency[3],&int_latency[4]); - sscanf(opcode_latency_fp, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_fp, "%u,%u,%u,%u,%u", &fp_latency[0],&fp_latency[1],&fp_latency[2], &fp_latency[3],&fp_latency[4]); - sscanf(opcode_latency_dp, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_dp, "%u,%u,%u,%u,%u", &dp_latency[0],&dp_latency[1],&dp_latency[2], &dp_latency[3],&dp_latency[4]); - sscanf(opcode_latency_sfu, "%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_sfu, "%u", &sfu_latency); - sscanf(opcode_latency_tensor, "%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_tensor, "%u", &tensor_latency); - sscanf(opcode_initiation_int, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_initiation_int, "%u,%u,%u,%u,%u", &int_init[0],&int_init[1],&int_init[2], &int_init[3],&int_init[4]); - sscanf(opcode_initiation_fp, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_initiation_fp, "%u,%u,%u,%u,%u", &fp_init[0],&fp_init[1],&fp_init[2], &fp_init[3],&fp_init[4]); - sscanf(opcode_initiation_dp, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_initiation_dp, "%u,%u,%u,%u,%u", &dp_init[0],&dp_init[1],&dp_init[2], &dp_init[3],&dp_init[4]); - sscanf(opcode_initiation_sfu, "%u", + sscanf(gpgpu_ctx->func_sim->opcode_initiation_sfu, "%u", &sfu_init); - sscanf(opcode_initiation_tensor, "%u", + sscanf(gpgpu_ctx->func_sim->opcode_initiation_tensor, "%u", &tensor_init); - sscanf(cdp_latency_str, "%u,%u,%u,%u,%u", - &cdp_latency[0],&cdp_latency[1],&cdp_latency[2], - &cdp_latency[3],&cdp_latency[4]); + sscanf(gpgpu_ctx->func_sim->cdp_latency_str, "%u,%u,%u,%u,%u", + &gpgpu_ctx->func_sim->cdp_latency[0], + &gpgpu_ctx->func_sim->cdp_latency[1], + &gpgpu_ctx->func_sim->cdp_latency[2], + &gpgpu_ctx->func_sim->cdp_latency[3], + &gpgpu_ctx->func_sim->cdp_latency[4]); if(!m_operands.empty()){ std::vector<operand_info>::iterator it; @@ -1102,7 +1087,7 @@ void ptx_instruction::pre_decode() } // get reconvergence pc - reconvergence_pc = get_converge_point(pc); + reconvergence_pc = gpgpu_ctx->func_sim->get_converge_point(pc); m_decoded=true; } @@ -1268,8 +1253,8 @@ void function_info::finalize( memory_space *param_mem ) void function_info::param_to_shared( memory_space *shared_mem, symbol_table *symtab ) { // TODO: call this only for PTXPlus with GT200 models - extern gpgpu_sim* g_the_gpu; - if (not g_the_gpu->get_config().convert_to_ptxplus()) return; + //extern gpgpu_sim* g_the_gpu; + if (not g_the_gpu()->get_config().convert_to_ptxplus()) return; // copies parameters into simulated shared memory for( std::map<unsigned,param_info>::iterator i=m_ptx_kernel_param_info.begin(); i!=m_ptx_kernel_param_info.end(); i++ ) { @@ -1466,7 +1451,7 @@ void function_info::ptx_jit_config(std::map<unsigned long long, size_t> mallocPt } template<int activate_level> -bool ptx_debug_exec_dump_cond(int thd_uid, addr_t pc) +bool cuda_sim::ptx_debug_exec_dump_cond(int thd_uid, addr_t pc) { if (g_debug_execution >= activate_level) { // check each type of debug dump constraint to filter out dumps @@ -1483,7 +1468,7 @@ bool ptx_debug_exec_dump_cond(int thd_uid, addr_t pc) return false; } -void init_inst_classification_stat() +void cuda_sim::init_inst_classification_stat() { static std::set<unsigned> init; if( init.find(g_ptx_kernel_count) != init.end() ) @@ -1552,7 +1537,8 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) } if ( g_debug_execution >= 6 || m_gpu->get_config().get_ptx_inst_debug_to_file()) { - if ( (g_debug_thread_uid==0) || (get_uid() == (unsigned)g_debug_thread_uid) ) { + if ( (m_gpu->gpgpu_ctx->func_sim->g_debug_thread_uid==0) + || (get_uid() == (unsigned)(m_gpu->gpgpu_ctx->func_sim->g_debug_thread_uid)) ) { clear_modifiedregs(); enable_debug_trace(); @@ -1624,11 +1610,11 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) fflush(m_gpu->get_ptx_inst_debug_file()); } - if ( ptx_debug_exec_dump_cond<5>(get_uid(), pc) ) { + if ( m_gpu->gpgpu_ctx->func_sim->ptx_debug_exec_dump_cond<5>(get_uid(), pc) ) { dim3 ctaid = get_ctaid(); dim3 tid = get_tid(); printf("%u [thd=%u][i=%u] : ctaid=(%u,%u,%u) tid=(%u,%u,%u) icount=%u [pc=%u] (%s:%u - %s) [0x%llx]\n", - g_ptx_sim_num_insn, + m_gpu->gpgpu_ctx->func_sim->g_ptx_sim_num_insn, get_uid(), pI->uid(), ctaid.x,ctaid.y,ctaid.z,tid.x,tid.y,tid.z, get_icount(), @@ -1678,22 +1664,22 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) } if ( g_debug_execution >= 6 ) { - if ( ptx_debug_exec_dump_cond<6>(get_uid(), pc) ) + if ( m_gpu->gpgpu_ctx->func_sim->ptx_debug_exec_dump_cond<6>(get_uid(), pc) ) dump_modifiedregs(stdout); } if ( g_debug_execution >= 10 ) { - if ( ptx_debug_exec_dump_cond<10>(get_uid(), pc) ) + if ( m_gpu->gpgpu_ctx->func_sim->ptx_debug_exec_dump_cond<10>(get_uid(), pc) ) dump_regs(stdout); } update_pc(); - g_ptx_sim_num_insn++; + m_gpu->gpgpu_ctx->func_sim->g_ptx_sim_num_insn++; //not using it with functional simulation mode if(!(this->m_functionalSimulationMode)) ptx_file_line_stats_add_exec_count(pI); - if ( gpgpu_ptx_instruction_classification ) { - init_inst_classification_stat(); + if ( m_gpu->gpgpu_ctx->func_sim->gpgpu_ptx_instruction_classification ) { + m_gpu->gpgpu_ctx->func_sim->init_inst_classification_stat(); unsigned space_type=0; switch ( pI->get_space().get_type() ) { case global_space: space_type = 10; break; @@ -1709,15 +1695,15 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) space_type = 0 ; break; } - StatAddSample( g_inst_classification_stat[g_ptx_kernel_count], op_classification); - if (space_type) StatAddSample( g_inst_classification_stat[g_ptx_kernel_count], ( int )space_type); - StatAddSample( g_inst_op_classification_stat[g_ptx_kernel_count], (int) pI->get_opcode() ); + StatAddSample( m_gpu->gpgpu_ctx->func_sim->g_inst_classification_stat[m_gpu->gpgpu_ctx->func_sim->g_ptx_kernel_count], op_classification); + if (space_type) StatAddSample( m_gpu->gpgpu_ctx->func_sim->g_inst_classification_stat[m_gpu->gpgpu_ctx->func_sim->g_ptx_kernel_count], ( int )space_type); + StatAddSample( m_gpu->gpgpu_ctx->func_sim->g_inst_op_classification_stat[m_gpu->gpgpu_ctx->func_sim->g_ptx_kernel_count], (int) pI->get_opcode() ); } - if ( (g_ptx_sim_num_insn % 100000) == 0 ) { + if ( (m_gpu->gpgpu_ctx->func_sim->g_ptx_sim_num_insn % 100000) == 0 ) { dim3 ctaid = get_ctaid(); dim3 tid = get_tid(); DPRINTF(LIVENESS, "GPGPU-Sim PTX: %u instructions simulated : ctaid=(%u,%u,%u) tid=(%u,%u,%u)\n", - g_ptx_sim_num_insn, ctaid.x,ctaid.y,ctaid.z,tid.x,tid.y,tid.z ); + m_gpu->gpgpu_ctx->func_sim->g_ptx_sim_num_insn, ctaid.x,ctaid.y,ctaid.z,tid.x,tid.y,tid.z ); fflush(stdout); } @@ -1740,7 +1726,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) } -void set_param_gpgpu_num_shaders(int num_shaders) +void cuda_sim::set_param_gpgpu_num_shaders(int num_shaders) { gpgpu_param_num_shaders = num_shaders; } @@ -1750,9 +1736,9 @@ const struct gpgpu_ptx_sim_info* ptx_sim_kernel_info(const function_info *kernel return kernel->get_kernel_info(); } -const warp_inst_t *ptx_fetch_inst( address_type pc ) +const warp_inst_t *gpgpu_context::ptx_fetch_inst( address_type pc ) { - return function_info::pc_to_instruction(pc); + return pc_to_instruction(pc); } unsigned ptx_sim_init_thread( kernel_info_t &kernel, @@ -1822,7 +1808,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, assert( max_cta_per_sm > 0 ); //unsigned sm_idx = (tid/cta_size)*gpgpu_param_num_shaders + sid; - unsigned sm_idx = hw_cta_id*gpgpu_param_num_shaders + sid; + unsigned sm_idx = hw_cta_id*gpu->gpgpu_ctx->func_sim->gpgpu_param_num_shaders + sid; if ( shared_memory_lookup.find(sm_idx) == shared_memory_lookup.end() ) { if ( g_debug_execution >= 1 ) { @@ -1836,7 +1822,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, snprintf(buf,512,"sstarr_%u", sid); sstarr_mem = new memory_space_impl<16*1024>(buf,4); sstarr_memory_lookup[sm_idx] = sstarr_mem; - cta_info = new ptx_cta_info(sm_idx); + cta_info = new ptx_cta_info(sm_idx, gpu->gpgpu_ctx); ptx_cta_lookup[sm_idx] = cta_info; } else { if ( g_debug_execution >= 1 ) { @@ -1920,7 +1906,7 @@ size_t get_kernel_code_size( class function_info *entry ) } -kernel_info_t *gpgpu_opencl_ptx_sim_init_grid(class function_info *entry, +kernel_info_t *cuda_sim::gpgpu_opencl_ptx_sim_init_grid(class function_info *entry, gpgpu_ptx_sim_arg_list_t args, struct dim3 gridDim, struct dim3 blockDim, @@ -1952,38 +1938,33 @@ void print_splash() } } -std::map<const void*,std::string> g_const_name_lookup; // indexed by hostVar -std::map<const void*,std::string> g_global_name_lookup; // indexed by hostVar -std::set<std::string> g_globals; -std::set<std::string> g_constants; - -void gpgpu_ptx_sim_register_const_variable(void *hostVar, const char *deviceName, size_t size ) +void cuda_sim::gpgpu_ptx_sim_register_const_variable(void *hostVar, const char *deviceName, size_t size ) { printf("GPGPU-Sim PTX registering constant %s (%zu bytes) to name mapping\n", deviceName, size ); g_const_name_lookup[hostVar] = deviceName; } -void gpgpu_ptx_sim_register_global_variable(void *hostVar, const char *deviceName, size_t size ) +void cuda_sim::gpgpu_ptx_sim_register_global_variable(void *hostVar, const char *deviceName, size_t size ) { printf("GPGPU-Sim PTX registering global %s hostVar to name mapping\n", deviceName ); g_global_name_lookup[hostVar] = deviceName; } -void gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, size_t count, size_t offset, int to, gpgpu_t *gpu ) +void cuda_sim::gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, size_t count, size_t offset, int to, gpgpu_t *gpu ) { printf("GPGPU-Sim PTX: starting gpgpu_ptx_sim_memcpy_symbol with hostVar 0x%p\n", hostVar); bool found_sym = false; memory_space_t mem_region = undefined_space; std::string sym_name; - std::map<const void*,std::string>::iterator c=g_const_name_lookup.find(hostVar); - if ( c!=g_const_name_lookup.end() ) { + std::map<const void*,std::string>::iterator c=gpu->gpgpu_ctx->func_sim->g_const_name_lookup.find(hostVar); + if ( c!=gpu->gpgpu_ctx->func_sim->g_const_name_lookup.end() ) { found_sym = true; sym_name = c->second; mem_region = const_space; } - std::map<const void*,std::string>::iterator g=g_global_name_lookup.find(hostVar); - if ( g!=g_global_name_lookup.end() ) { + std::map<const void*,std::string>::iterator g=gpu->gpgpu_ctx->func_sim->g_global_name_lookup.find(hostVar); + if ( g!=gpu->gpgpu_ctx->func_sim->g_global_name_lookup.end() ) { if ( found_sym ) { printf("Execution error: PTX symbol \"%s\" w/ hostVar=0x%Lx is declared both const and global?\n", sym_name.c_str(), (unsigned long long)hostVar ); @@ -2011,8 +1992,8 @@ void gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, size_t co const char *mem_name = NULL; memory_space *mem = NULL; - std::map<std::string,symbol_table*>::iterator st = g_sym_name_to_symbol_table.find(sym_name.c_str()); - assert( st != g_sym_name_to_symbol_table.end() ); + std::map<std::string,symbol_table*>::iterator st = gpgpu_ctx->ptx_parser->g_sym_name_to_symbol_table.find(sym_name.c_str()); + assert( st != gpgpu_ctx->ptx_parser->g_sym_name_to_symbol_table.end() ); symbol_table *symtab = st->second; symbol *sym = symtab->lookup(sym_name.c_str()); @@ -2039,13 +2020,9 @@ void gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, size_t co fflush(stdout); } -int g_ptx_sim_mode; // if non-zero run functional simulation only (i.e., no notion of a clock cycle) - extern int ptx_debug; -bool g_cuda_launch_blocking = false; - -void read_sim_environment_variables() +void cuda_sim::read_sim_environment_variables() { ptx_debug = 0; g_debug_execution = 0; @@ -2103,8 +2080,6 @@ void read_sim_environment_variables() } } -ptx_cta_info *g_func_cta_info = NULL; - #define MAX(a,b) (((a)>(b))?(a):(b)) unsigned max_cta (const struct gpgpu_ptx_sim_info *kernel_info, unsigned threads_per_cta, unsigned int warp_size, unsigned int n_thread_per_shader, unsigned int gpgpu_shmem_size, unsigned int gpgpu_shader_registers, unsigned int max_cta_per_core) @@ -2143,12 +2118,12 @@ unsigned max_cta (const struct gpgpu_ptx_sim_info *kernel_info, unsigned threads This function simulates the CUDA code functionally, it takes a kernel_info_t parameter which holds the data for the CUDA kernel to be executed !*/ -void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) +void cuda_sim::gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) { printf("GPGPU-Sim: Performing Functional Simulation, executing kernel %s...\n",kernel.name().c_str()); //using a shader core object for book keeping, it is not needed but as most function built for performance simulation need it we use it here - extern gpgpu_sim *g_the_gpu; + //extern gpgpu_sim *g_the_gpu; //before we execute, we should do PDOM analysis for functional simulation scenario. function_info *kernel_func_info = kernel.entry(); const struct gpgpu_ptx_sim_info *kernel_info = ptx_sim_kernel_info(kernel_func_info); @@ -2163,7 +2138,7 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) kernel_func_info->set_pdom(); } - unsigned max_cta_tot = max_cta(kernel_info,kernel.threads_per_cta(), g_the_gpu->getShaderCoreConfig()->warp_size, g_the_gpu->getShaderCoreConfig()->n_thread_per_shader, g_the_gpu->getShaderCoreConfig()->gpgpu_shmem_size, g_the_gpu->getShaderCoreConfig()->gpgpu_shader_registers, g_the_gpu->getShaderCoreConfig()->max_cta_per_core); + unsigned max_cta_tot = max_cta(kernel_info,kernel.threads_per_cta(), g_the_gpu()->getShaderCoreConfig()->warp_size, g_the_gpu()->getShaderCoreConfig()->n_thread_per_shader, g_the_gpu()->getShaderCoreConfig()->gpgpu_shmem_size, g_the_gpu()->getShaderCoreConfig()->gpgpu_shader_registers, g_the_gpu()->getShaderCoreConfig()->max_cta_per_core); printf("Max CTA : %d\n",max_cta_tot); @@ -2171,11 +2146,11 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) int inst_count=50; - int cp_op= g_the_gpu->checkpoint_option; - int cp_CTA = g_the_gpu->checkpoint_CTA; - int cp_kernel= g_the_gpu->checkpoint_kernel; - cp_count= g_the_gpu->checkpoint_insn_Y; - cp_cta_resume= g_the_gpu->checkpoint_CTA_t; + int cp_op= g_the_gpu()->checkpoint_option; + int cp_CTA = g_the_gpu()->checkpoint_CTA; + int cp_kernel= g_the_gpu()->checkpoint_kernel; + cp_count= g_the_gpu()->checkpoint_insn_Y; + cp_cta_resume= g_the_gpu()->checkpoint_CTA_t; int cta_launched =0; //we excute the kernel one CTA (Block) at the time, as synchronization functions work block wise @@ -2187,13 +2162,13 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) { functionalCoreSim cta( &kernel, - g_the_gpu, - g_the_gpu->getShaderCoreConfig()->warp_size + g_the_gpu(), + g_the_gpu()->getShaderCoreConfig()->warp_size ); cta.execute(cp_count,temp); #if (CUDART_VERSION >= 5000) - launch_all_device_kernels(); + gpgpu_ctx->device_runtime->launch_all_device_kernels(); #endif } else @@ -2209,7 +2184,7 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) { char f1name[2048]; snprintf(f1name,2048,"checkpoint_files/global_mem_%d.txt", kernel.get_uid() ); - g_checkpoint->store_global_mem(g_the_gpu->get_global_memory(), f1name , "%08x"); + g_checkpoint->store_global_mem(g_the_gpu()->get_global_memory(), f1name , "%08x"); } @@ -2219,8 +2194,8 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) //openCL kernel simulation calls don't register the kernel so we don't register its exit if(!openCL) { - extern stream_manager *g_stream_manager; - g_stream_manager->register_finished_kernel(kernel.get_uid()); + //extern stream_manager *g_stream_manager; + g_stream_manager()->register_finished_kernel(kernel.get_uid()); } //******PRINTING******* @@ -2235,7 +2210,7 @@ void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL ) //g_simulation_starttime is initilized by gpgpu_ptx_sim_init_perf() in gpgpusim_entrypoint.cc upon starting gpgpu-sim time_t end_time, elapsed_time, days, hrs, minutes, sec; end_time = time((time_t *)NULL); - elapsed_time = MAX(end_time - g_simulation_starttime, 1); + elapsed_time = MAX(end_time - GPGPUsim_ctx_ptr()->g_simulation_starttime, 1); //calculating and printing simulation time in terms of days, hours, minutes and seconds @@ -2269,7 +2244,7 @@ void functionalCoreSim::initializeCTA(unsigned ctaid_cp) assert(m_thread[i]!=NULL && !m_thread[i]->is_done()); char fname[2048]; snprintf(fname,2048,"checkpoint_files/thread_%d_0_reg.txt",i ); - if(cp_cta_resume==1) + if(m_gpu->gpgpu_ctx->func_sim->cp_cta_resume==1) m_thread[i]->resume_reg_thread(fname,symtab); ctaLiveThreads++; } @@ -2293,7 +2268,7 @@ void functionalCoreSim::createWarp(unsigned warpId) char fname[2048]; snprintf(fname,2048,"checkpoint_files/warp_%d_0_simt.txt",warpId ); - if(cp_cta_resume==1) + if(m_gpu->gpgpu_ctx->func_sim->cp_cta_resume==1) { unsigned pc,rpc; m_simt_stack[warpId]->resume(fname); @@ -2309,8 +2284,8 @@ void functionalCoreSim::createWarp(unsigned warpId) void functionalCoreSim::execute(int inst_count, unsigned ctaid_cp) { - cp_count= m_gpu->checkpoint_insn_Y; - cp_cta_resume= m_gpu->checkpoint_CTA_t; + m_gpu->gpgpu_ctx->func_sim->cp_count= m_gpu->checkpoint_insn_Y; + m_gpu->gpgpu_ctx->func_sim->cp_cta_resume= m_gpu->checkpoint_CTA_t; initializeCTA(ctaid_cp); int count=0; @@ -2389,11 +2364,11 @@ void functionalCoreSim::executeWarp(unsigned i, bool &allAtBarrier, bool & someO if(!m_warpAtBarrier[i]&& m_liveThreadCount[i]>0) allAtBarrier = false; } -unsigned translate_pc_to_ptxlineno(unsigned pc) +unsigned gpgpu_context::translate_pc_to_ptxlineno(unsigned pc) { // this function assumes that the kernel fits inside a single PTX file // function_info *pFunc = g_func_info; // assume that the current kernel is the one in query - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = pc_to_instruction(pc); unsigned ptx_line_number = pInsn->source_line(); return ptx_line_number; @@ -2403,8 +2378,6 @@ unsigned translate_pc_to_ptxlineno(unsigned pc) extern std::map<unsigned,const char*> get_duplicate(); -int g_ptxinfo_error_detected; - static char *g_ptxinfo_kname = NULL; static struct gpgpu_ptx_sim_info g_ptxinfo; static std::map<unsigned,const char*> g_duplicate; @@ -2532,14 +2505,7 @@ void ptxinfo_opencl_addinfo( std::map<std::string,function_info*> &kernels ) clear_ptxinfo(); } -struct rec_pts { - gpgpu_recon_t *s_kernel_recon_points; - int s_num_recon; -}; - -class std::map<function_info*,rec_pts> g_rpts; - -struct rec_pts find_reconvergence_points( function_info *finfo ) +struct rec_pts cuda_sim::find_reconvergence_points( function_info *finfo ) { rec_pts tmp; std::map<function_info*,rec_pts>::iterator r=g_rpts.find(finfo); @@ -2578,7 +2544,7 @@ address_type get_return_pc( void *thd ) return the_thread->get_return_PC(); } -address_type get_converge_point( address_type pc ) +address_type cuda_sim::get_converge_point( address_type pc ) { // the branch could encode the reconvergence point and/or a bit that indicates the // reconvergence point is the return PC on the call stack in the case the branch has diff --git a/src/cuda-sim/cuda-sim.h b/src/cuda-sim/cuda-sim.h index e690356..1be3d19 100644 --- a/src/cuda-sim/cuda-sim.h +++ b/src/cuda-sim/cuda-sim.h @@ -36,33 +36,16 @@ #include <string> #include"ptx_sim.h" +class gpgpu_context; class memory_space; class function_info; class symbol_table; extern const char *g_gpgpusim_version_string; -extern int g_ptx_sim_mode; extern int g_debug_execution; -extern int g_debug_thread_uid; -extern void ** g_inst_classification_stat; -extern void ** g_inst_op_classification_stat; -extern int g_ptx_kernel_count; // used for classification stat collection purposes -extern char *opcode_latency_int, *opcode_latency_fp, *opcode_latency_dp,*opcode_latency_sfu,*opcode_latency_tensor; - -void ptx_opcocde_latency_options (option_parser_t opp); -extern class kernel_info_t *gpgpu_opencl_ptx_sim_init_grid(class function_info *entry, - gpgpu_ptx_sim_arg_list_t args, - struct dim3 gridDim, - struct dim3 blockDim, - class gpgpu_t *gpu ); -extern void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL = false ); extern void print_splash(); -extern void gpgpu_ptx_sim_register_const_variable(void*, const char *deviceName, size_t size ); -extern void gpgpu_ptx_sim_register_global_variable(void *hostVar, const char *deviceName, size_t size ); -extern void gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, size_t count, size_t offset, int to, gpgpu_t *gpu ); -extern void read_sim_environment_variables(); extern void ptxinfo_opencl_addinfo( std::map<std::string,function_info*> &kernels ); unsigned ptx_sim_init_thread( kernel_info_t &kernel, class ptx_thread_info** thread_info, @@ -75,12 +58,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, unsigned hw_warp_id, gpgpu_t *gpu, bool functionalSimulationMode = false); -const warp_inst_t *ptx_fetch_inst( address_type pc ); const struct gpgpu_ptx_sim_info* ptx_sim_kernel_info(const class function_info *kernel); -void ptx_print_insn( address_type pc, FILE *fp ); -std::string ptx_get_insn_str( address_type pc ); -void set_param_gpgpu_num_shaders(int num_shaders); - /*! * This class functionally executes a kernel. It uses the basic data structures and procedures in core_t @@ -134,4 +112,91 @@ void print_ptxinfo(); void clear_ptxinfo(); struct gpgpu_ptx_sim_info get_ptxinfo(); +class gpgpu_recon_t; +struct rec_pts { + gpgpu_recon_t *s_kernel_recon_points; + int s_num_recon; +}; + + +class cuda_sim { + public: + cuda_sim( gpgpu_context* ctx ) { + g_ptx_sim_num_insn = 0; + g_ptx_kernel_count = -1; // used for classification stat collection purposes + gpgpu_param_num_shaders = 0; + g_cuda_launch_blocking = false; + g_inst_classification_stat = NULL; + g_inst_op_classification_stat= NULL; + g_assemble_code_next_pc=0; + g_debug_thread_uid = 0; + g_override_embedded_ptx = false; + ptx_tex_regs = NULL; + g_ptx_thread_info_delete_count=0; + g_ptx_thread_info_uid_next=1; + g_debug_pc = 0xBEEF1518; + gpgpu_ctx = ctx; + } + //global variables + char *opcode_latency_int; + char *opcode_latency_fp; + char *opcode_latency_dp; + char *opcode_latency_sfu; + char *opcode_latency_tensor; + char *opcode_initiation_int; + char *opcode_initiation_fp; + char *opcode_initiation_dp; + char *opcode_initiation_sfu; + char *opcode_initiation_tensor; + int cp_count; + int cp_cta_resume; + int g_ptxinfo_error_detected; + unsigned g_ptx_sim_num_insn; + char *cdp_latency_str; + int g_ptx_kernel_count; // used for classification stat collection purposes + std::map<const void*,std::string> g_global_name_lookup; // indexed by hostVar + std::map<const void*,std::string> g_const_name_lookup; // indexed by hostVar + int g_ptx_sim_mode; // if non-zero run functional simulation only (i.e., no notion of a clock cycle) + unsigned gpgpu_param_num_shaders; + class std::map<function_info*,rec_pts> g_rpts; + bool g_cuda_launch_blocking; + void ** g_inst_classification_stat; + void ** g_inst_op_classification_stat; + std::set<std::string> g_globals; + std::set<std::string> g_constants; + std::map<unsigned,function_info*> g_pc_to_finfo; + int gpgpu_ptx_instruction_classification; + unsigned cdp_latency[5]; + unsigned g_assemble_code_next_pc; + int g_debug_thread_uid; + bool g_override_embedded_ptx; + std::set<unsigned long long> g_ptx_cta_info_sm_idx_used; + ptx_reg_t* ptx_tex_regs; + unsigned g_ptx_thread_info_delete_count; + unsigned g_ptx_thread_info_uid_next; + addr_t g_debug_pc; + // backward pointer + class gpgpu_context* gpgpu_ctx; + //global functions + void ptx_opcocde_latency_options (option_parser_t opp); + void gpgpu_cuda_ptx_sim_main_func( kernel_info_t &kernel, bool openCL = false ); + int gpgpu_opencl_ptx_sim_main_func( kernel_info_t *grid ); + void init_inst_classification_stat(); + kernel_info_t *gpgpu_opencl_ptx_sim_init_grid(class function_info *entry, + gpgpu_ptx_sim_arg_list_t args, + struct dim3 gridDim, + struct dim3 blockDim, + gpgpu_t *gpu ); + void gpgpu_ptx_sim_register_global_variable(void *hostVar, const char *deviceName, size_t size ); + void gpgpu_ptx_sim_register_const_variable(void*, const char *deviceName, size_t size ); + void read_sim_environment_variables(); + void set_param_gpgpu_num_shaders(int num_shaders); + struct rec_pts find_reconvergence_points( function_info *finfo ); + address_type get_converge_point( address_type pc ); + void gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, size_t count, size_t offset, int to, gpgpu_t *gpu ); + void ptx_print_insn( address_type pc, FILE *fp ); + std::string ptx_get_insn_str( address_type pc ); + template<int activate_level> bool ptx_debug_exec_dump_cond(int thd_uid, addr_t pc); +}; + #endif diff --git a/src/cuda-sim/cuda_device_runtime.cc b/src/cuda-sim/cuda_device_runtime.cc index 917e7a8..dc3adc3 100644 --- a/src/cuda-sim/cuda_device_runtime.cc +++ b/src/cuda-sim/cuda_device_runtime.cc @@ -5,8 +5,6 @@ #include <iostream> #include <map> -unsigned long long g_total_param_size = 0; -unsigned long long g_max_total_param_size = 0; #if (CUDART_VERSION >= 5000) @@ -18,7 +16,9 @@ unsigned long long g_max_total_param_size = 0; #include "cuda-sim.h" #include "ptx_ir.h" #include "../stream_manager.h" +#include "../gpgpusim_entrypoint.h" #include "cuda_device_runtime.h" +#include "../../libcuda/gpgpu_context.h" #define DEV_RUNTIME_REPORT(a) \ if( g_debug_execution ) { \ @@ -26,49 +26,12 @@ unsigned long long g_max_total_param_size = 0; std::cout.flush(); \ } -class device_launch_config_t { -public: - device_launch_config_t() {} - - device_launch_config_t(dim3 _grid_dim, - dim3 _block_dim, - unsigned int _shared_mem, - function_info * _entry): - grid_dim(_grid_dim), - block_dim(_block_dim), - shared_mem(_shared_mem), - entry(_entry) {} - - dim3 grid_dim; - dim3 block_dim; - unsigned int shared_mem; - function_info * entry; - -}; - -class device_launch_operation_t { - -public: - device_launch_operation_t() {} - device_launch_operation_t(kernel_info_t *_grid, - CUstream_st * _stream) : - grid(_grid), stream(_stream) {} - - kernel_info_t * grid; //a new child grid - - CUstream_st * stream; - -}; - - -std::map<void *, device_launch_config_t> g_cuda_device_launch_param_map; -std::list<device_launch_operation_t> g_cuda_device_launch_op; -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) -void gpgpusim_cuda_getParameterBufferV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func) +void cuda_device_runtime::gpgpusim_cuda_getParameterBufferV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func) { DEV_RUNTIME_REPORT("Calling cudaGetParameterBufferV2"); @@ -141,7 +104,7 @@ void gpgpusim_cuda_getParameterBufferV2(const ptx_instruction * pI, ptx_thread_i //Handling device runtime api: //cudaError_t cudaLaunchDeviceV2(void *parameterBuffer, cudaStream_t stream) -void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func) { +void cuda_device_runtime::gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func) { DEV_RUNTIME_REPORT("Calling cudaLaunchDeviceV2"); unsigned n_return = target_func->has_return(); @@ -200,7 +163,7 @@ void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info * //create child kernel_info_t and index it with parameter_buffer address gpgpu_t* gpu=thread->get_gpu(); device_grid = new kernel_info_t(config.grid_dim, config.block_dim, device_kernel_entry, gpu->getNameArrayMapping(), gpu->getNameInfoMapping()); - device_grid->launch_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; + device_grid->launch_cycle = gpu->gpu_sim_cycle + gpu->gpu_tot_sim_cycle; 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 << @@ -262,7 +225,7 @@ void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info * //Handling device runtime api: //cudaError_t cudaStreamCreateWithFlags ( cudaStream_t* pStream, unsigned int flags) //flags can only be cudaStreamNonBlocking -void gpgpusim_cuda_streamCreateWithFlags(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func) { +void cuda_device_runtime::gpgpusim_cuda_streamCreateWithFlags(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func) { DEV_RUNTIME_REPORT("Calling cudaStreamCreateWithFlags"); unsigned n_return = target_func->has_return(); @@ -317,17 +280,17 @@ void gpgpusim_cuda_streamCreateWithFlags(const ptx_instruction * pI, ptx_thread_ } -void launch_one_device_kernel() { +void cuda_device_runtime::launch_one_device_kernel() { if(!g_cuda_device_launch_op.empty()) { device_launch_operation_t &op = g_cuda_device_launch_op.front(); - stream_operation stream_op = stream_operation(op.grid, g_ptx_sim_mode, op.stream); - g_stream_manager->push(stream_op); + stream_operation stream_op = stream_operation(op.grid, gpgpu_ctx->func_sim->g_ptx_sim_mode, op.stream); + g_stream_manager()->push(stream_op); g_cuda_device_launch_op.pop_front(); } } -void launch_all_device_kernels() { +void cuda_device_runtime::launch_all_device_kernels() { while(!g_cuda_device_launch_op.empty()) { launch_one_device_kernel(); } diff --git a/src/cuda-sim/cuda_device_runtime.h b/src/cuda-sim/cuda_device_runtime.h index 6dbcd71..7f7a0ca 100644 --- a/src/cuda-sim/cuda_device_runtime.h +++ b/src/cuda-sim/cuda_device_runtime.h @@ -1,11 +1,68 @@ +#ifndef __cuda_device_runtime_h__ +#define __cuda_device_runtime_h__ //Jin: cuda_device_runtime.h //Defines CUDA device runtime APIs for CDP support +class device_launch_config_t { + +public: + device_launch_config_t() {} + + device_launch_config_t(dim3 _grid_dim, + dim3 _block_dim, + unsigned int _shared_mem, + function_info * _entry): + grid_dim(_grid_dim), + block_dim(_block_dim), + shared_mem(_shared_mem), + entry(_entry) {} + + dim3 grid_dim; + dim3 block_dim; + unsigned int shared_mem; + function_info * entry; + +}; + +class device_launch_operation_t { + +public: + device_launch_operation_t() {} + device_launch_operation_t(kernel_info_t *_grid, + CUstream_st * _stream) : + grid(_grid), stream(_stream) {} + + kernel_info_t * grid; //a new child grid + + CUstream_st * stream; + +}; + +class gpgpu_context; + +class cuda_device_runtime { + public: + cuda_device_runtime( gpgpu_context* ctx ) { + g_total_param_size = 0; + g_max_total_param_size = 0; + gpgpu_ctx = ctx; + } + unsigned long long g_total_param_size; + std::map<void *, device_launch_config_t> g_cuda_device_launch_param_map; + std::list<device_launch_operation_t> g_cuda_device_launch_op; + unsigned g_kernel_launch_latency; + unsigned long long g_max_total_param_size; + bool g_cdp_enabled; + + // backward pointer + class gpgpu_context* gpgpu_ctx; #if (CUDART_VERSION >= 5000) #pragma once - -void gpgpusim_cuda_getParameterBufferV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func); -void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func); -void gpgpusim_cuda_streamCreateWithFlags(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func); -void launch_all_device_kernels(); -void launch_one_device_kernel(); + void gpgpusim_cuda_launchDeviceV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func); + void gpgpusim_cuda_streamCreateWithFlags(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func); + void gpgpusim_cuda_getParameterBufferV2(const ptx_instruction * pI, ptx_thread_info * thread, const function_info * target_func); + void launch_all_device_kernels(); + void launch_one_device_kernel(); #endif +}; + +#endif /* __cuda_device_runtime_h__ */ diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 11001d7..58a077e 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -31,6 +31,8 @@ #include "ptx_ir.h" #include "opcodes.h" #include "ptx_sim.h" +typedef void * yyscan_t; +class ptx_recognizer; #include "ptx.tab.h" #include <stdlib.h> #include <math.h> @@ -54,10 +56,10 @@ #include "cuda_device_runtime.h" #include <stdarg.h> +#include "../../libcuda/gpgpu_context.h" + using half_float::half; -unsigned ptx_instruction::g_num_ptx_inst_uid=0; -bool debug_tensorcore = 0; const char *g_opcode_string[NUM_OPCODES] = { @@ -1526,6 +1528,7 @@ void bar_impl( const ptx_instruction *pIin, ptx_thread_info *thread ) op2_data = thread->get_operand_value(op2, op2, PRED_TYPE, thread, 1); op2_data.u32=!(op2_data.pred & 0x0001); pI->set_bar_id(op1_data.u32); + pI->set_bar_count(thread->get_ntid().x * thread->get_ntid().y * thread->get_ntid().z); switch(red_op){ case ATOMIC_POPC: thread->popc_reduction(ctaid,op1_data.u32,op2_data.u32); @@ -1836,14 +1839,14 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) for (thrd=0; thrd < core->get_warp_size(); thrd++){ thread = core->get_thread_info()[tid+thrd]; - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("THREAD=%d\n:",thrd); for(int operand_num=1;operand_num<=3;operand_num++){ const operand_info &src_a= pI->operand_lookup(operand_num); unsigned nelem = src_a.get_vect_nelem(); ptx_reg_t v[8]; thread->get_vector_operand_values( src_a, v, nelem ); - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ printf("Thread%d_Iteration=%d\n:",thrd,operand_num); for(k=0;k<nelem;k++){ printf("%x ",v[k].u64); @@ -1865,14 +1868,14 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) if(!((operand_num==3)&&(type2==F32_TYPE))){ for(k=0;k<2*nelem;k++){ temp=nw_v[k].f16; - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("%.2f ",temp); } - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("\n"); } else{ - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ for(k=0;k<8;k++){ printf("%.2f ",v[k].f32); } @@ -1883,7 +1886,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) case 1 ://operand 1 for(k=0;k<8;k++){ mapping(thrd,LOAD_A,a_layout,F16_TYPE,k,16,row,col,offset); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("A:thread=%d,row=%d,col=%d,offset=%d\n",thrd,row,col,offset); matrix_a[row][col]=nw_v[offset]; } @@ -1891,7 +1894,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) case 2 ://operand 2 for(k=0;k<8;k++){ mapping(thrd,LOAD_B,b_layout,F16_TYPE,k,16,row,col,offset); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("B:thread=%d,row=%d,col=%d,offset=%d\n",thrd,row,col,offset); matrix_b[row][col]=nw_v[offset]; } @@ -1899,7 +1902,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) case 3 ://operand 3 for(k=0;k<8;k++){ mapping(thrd,LOAD_C,ROW,type2,k,16,row,col,offset); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("C:thread=%d,row=%d,col=%d,offset=%d\n",thrd,row,col,offset); if(type2!=F16_TYPE){ matrix_c[row][col]=v[offset]; @@ -1913,10 +1916,10 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) printf("Invalid Operand Index\n" ); } } - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("\n"); } - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ printf("MATRIX_A\n"); for (i=0;i<16;i++){ for(j=0;j<16;j++){ @@ -1976,7 +1979,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } } } - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ printf("MATRIX_D\n"); for (i=0;i<16;i++){ for(j=0;j<16;j++){ @@ -1995,7 +1998,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) int col_t[8]; for(k=0;k<8;k++){ mapping(thrd,LOAD_C,ROW,type,k,16,row_t[k],col_t[k],offset); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("mma:store:row:%d,col%d\n",row_t[k],col_t[k]); } thread = core->get_thread_info()[tid+thrd]; @@ -2004,7 +2007,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) if(type==F32_TYPE){ thread->set_wmma_vector_operand_values(dst,matrix_d[row_t[0]][col_t[0]],matrix_d[row_t[1]][col_t[1]],matrix_d[row_t[2]][col_t[2]],matrix_d[row_t[3]][col_t[3]],matrix_d[row_t[4]][col_t[4]],matrix_d[row_t[5]][col_t[5]],matrix_d[row_t[6]][col_t[6]],matrix_d[row_t[7]][col_t[7]]); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) { printf("thread%d:",thrd); for(k=0;k<8;k++){ @@ -2014,7 +2017,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } } else if(type==F16_TYPE){ - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ printf("thread%d:",thrd); for(k=0;k<8;k++){ temp=matrix_d[row_t[k]][col_t[k]].f16; @@ -2034,7 +2037,7 @@ void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) nw_data3.s64=((matrix_d[row_t[4]][col_t[4]].s64 & 0xffff))|((matrix_d[row_t[5]][col_t[5]].s64&0xffff)<<16); nw_data4.s64=((matrix_d[row_t[6]][col_t[6]].s64 & 0xffff))|((matrix_d[row_t[7]][col_t[7]].s64&0xffff)<<16); thread->set_vector_operand_values(dst,nw_data1,nw_data2,nw_data3,nw_data4); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("thread%d=%x,%x,%x,%x",thrd,nw_data1.s64,nw_data2.s64,nw_data3.s64,nw_data4.s64); } @@ -2092,15 +2095,15 @@ void call_impl( const ptx_instruction *pI, ptx_thread_info *thread ) #if (CUDART_VERSION >= 5000) //Jin: handle device runtime apis for CDP else if(fname == "cudaGetParameterBufferV2") { - gpgpusim_cuda_getParameterBufferV2(pI, thread, target_func); + target_func->gpgpu_ctx->device_runtime->gpgpusim_cuda_getParameterBufferV2(pI, thread, target_func); return; } else if(fname == "cudaLaunchDeviceV2") { - gpgpusim_cuda_launchDeviceV2(pI, thread, target_func); + target_func->gpgpu_ctx->device_runtime->gpgpusim_cuda_launchDeviceV2(pI, thread, target_func); return; } else if(fname == "cudaStreamCreateWithFlags") { - gpgpusim_cuda_streamCreateWithFlags(pI, thread, target_func); + target_func->gpgpu_ctx->device_runtime->gpgpusim_cuda_streamCreateWithFlags(pI, thread, target_func); return; } #endif @@ -2300,12 +2303,12 @@ ptx_reg_t f2x( ptx_reg_t x, unsigned from_width, unsigned to_width, int to_sign, half_float::half tmp_h; //assert( from_width == 32); - enum cuda_math::cudaRoundMode mode = cuda_math::cudaRoundZero; + enum cudaRoundMode mode = cudaRoundZero; switch (rounding_mode) { - case RZI_OPTION: mode = cuda_math::cudaRoundZero; break; - case RNI_OPTION: mode = cuda_math::cudaRoundNearest; break; - case RMI_OPTION: mode = cuda_math::cudaRoundMinInf; break; - case RPI_OPTION: mode = cuda_math::cudaRoundPosInf; break; + case RZI_OPTION: mode = cudaRoundZero; break; + case RNI_OPTION: mode = cudaRoundNearest; break; + case RMI_OPTION: mode = cudaRoundMinInf; break; + case RPI_OPTION: mode = cudaRoundPosInf; break; default: break; } @@ -3128,7 +3131,7 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t &inst ) decode_space(space,thread,src1,mem,addr); type_info_key::type_decode(type,size,t); - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("mma_st: thrd=%d,addr=%x, fp(size=%d), stride=%d\n",thrd,addr_reg.u32,size,src2_data.u32); addr_t new_addr = addr+thread_group_offset(thrd,wmma_type,wmma_layout,type,stride)*size/8; addr_t push_addr; @@ -3148,7 +3151,7 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t &inst ) mem->write(push_addr,size/8,&v[k].s64,thread,pI); mem_txn_addr[num_mem_txn++]=push_addr; - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ printf("wmma:store:thread%d=%x,%x,%x,%x,%x,%x,%x,%x\n",thrd,v[0].s64,v[1].s64,v[2].s64,v[3].s64,v[4].s64,v[5].s64,v[6].s64,v[7].s64); float temp; int l; @@ -3175,7 +3178,7 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t &inst ) mem_txn_addr[num_mem_txn++]=push_addr; } - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("wmma:store:thread%d=%x,%x,%x,%x,%x,%x,%x,%x\n",thrd,nw_v[0].s64,nw_v[1].s64,nw_v[2].s64,nw_v[3].s64,nw_v[4].s64,nw_v[5].s64,nw_v[6].s64,nw_v[7].s64); } } @@ -3238,7 +3241,7 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t &inst ) type_info_key::type_decode(type,size,t); ptx_reg_t data[16]; - if(debug_tensorcore) + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore) printf("mma_ld: thrd=%d,addr=%x, fpsize=%d, stride=%d\n",thrd,src1_data.u32,size,src2_data.u32); addr_t new_addr = addr+thread_group_offset(thrd,wmma_type,wmma_layout,type,stride)*size/8; @@ -3334,7 +3337,7 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t &inst ) inst.data_size = 4; // 4 byte transaction assert( inst.memory_op == insn_memory_op ); - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ if(type==F16_TYPE){ printf("\nmma_ld:thread%d= ",thrd); for(i=0;i<16;i++){ @@ -3384,7 +3387,7 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t &inst ) thread->set_vector_operand_values(dst,nw_data[0],nw_data[1],nw_data[2],nw_data[3]); else thread->set_wmma_vector_operand_values(dst,nw_data[0],nw_data[1],nw_data[2],nw_data[3],nw_data[4],nw_data[5],nw_data[6],nw_data[7]); - if(debug_tensorcore){ + if(core->get_gpu()->gpgpu_ctx->debug_tensorcore){ printf("mma_ld:data[0].s64=%x,data[1].s64=%x,new_data[0].s64=%x\n",data[0].u64,data[1].u64,nw_data[0].u64); printf("mma_ld:data[2].s64=%x,data[3].s64=%x,new_data[1].s64=%x\n",data[2].u64,data[3].u64,nw_data[1].u64); printf("mma_ld:data[4].s64=%x,data[5].s64=%x,new_data[2].s64=%x\n",data[4].u64,data[5].u64,nw_data[2].u64); @@ -5141,7 +5144,6 @@ void sured_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not void sust_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } void suq_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } -ptx_reg_t* ptx_tex_regs = NULL; union intfloat { int a; @@ -5255,9 +5257,10 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) unsigned c_type = pI->get_type2(); fflush(stdout); ptx_reg_t data1, data2, data3, data4; - if (!ptx_tex_regs) ptx_tex_regs = new ptx_reg_t[4]; + if (!thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs) + thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs = new ptx_reg_t[4]; unsigned nelem = src2.get_vect_nelem(); - thread->get_vector_operand_values(src2, ptx_tex_regs, nelem); //ptx_reg should be 4 entry vector type...coordinates into texture + thread->get_vector_operand_values(src2, thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs, nelem); //ptx_reg should be 4 entry vector type...coordinates into texture /* For programs with many streams, textures can be bound and unbound asynchronously. This means we need to use the kernel's "snapshot" of @@ -5294,7 +5297,7 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) height = cuArray->height; if (texref->normalized) { assert(c_type == F32_TYPE); - x_f32 = ptx_tex_regs[0].f32; + x_f32 = thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[0].f32; if (texref->addressMode[0] == cudaAddressModeClamp) { x_f32 = (x_f32 > 1.0)? 1.0 : x_f32; x_f32 = (x_f32 < 0.0)? 0.0 : x_f32; @@ -5317,11 +5320,11 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) } else { switch ( c_type ) { case S32_TYPE: - x = ptx_tex_regs[0].s32; + x = thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[0].s32; assert(texref->filterMode == cudaFilterModePoint); break; case F32_TYPE: - x_f32 = ptx_tex_regs[0].f32; + x_f32 = thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[0].f32; alpha = x_f32 - floor(x_f32); // offset into subtexel (for linear sampling) x = (int) x_f32; break; @@ -5344,8 +5347,8 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) width = cuArray->width; height = cuArray->height; if (texref->normalized) { - x_f32 = reduce_precision(ptx_tex_regs[0].f32,16); - y_f32 = reduce_precision(ptx_tex_regs[1].f32,15); + x_f32 = reduce_precision(thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[0].f32,16); + y_f32 = reduce_precision(thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[1].f32,15); if (texref->addressMode[0]) {//clamp if (x_f32<0) x_f32 = 0; @@ -5375,8 +5378,8 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) y = (int) floor(y_f32 * height); } } else { - x_f32 = ptx_tex_regs[0].f32; - y_f32 = ptx_tex_regs[1].f32; + x_f32 = thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[0].f32; + y_f32 = thread->get_gpu()->gpgpu_ctx->func_sim->ptx_tex_regs[1].f32; alpha = x_f32 - floor(x_f32); beta = y_f32 - floor(y_f32); diff --git a/src/cuda-sim/memory.cc b/src/cuda-sim/memory.cc index 9554f55..4b2acdf 100644 --- a/src/cuda-sim/memory.cc +++ b/src/cuda-sim/memory.cc @@ -28,6 +28,7 @@ #include "memory.h" #include <stdlib.h> #include "../debug.h" +#include "../../libcuda/gpgpu_context.h" template<unsigned BSIZE> memory_space_impl<BSIZE>::memory_space_impl( std::string name, unsigned hash_size ) { @@ -88,7 +89,7 @@ template<unsigned BSIZE> void memory_space_impl<BSIZE>::write( mem_addr_t addr, for( i=m_watchpoints.begin(); i!=m_watchpoints.end(); i++ ) { mem_addr_t wa = i->second; if( ((addr<=wa) && ((addr+length)>wa)) || ((addr>wa) && (addr < (wa+4))) ) - hit_watchpoint(i->first,thd,pI); + thd->get_gpu()->gpgpu_ctx->the_gpgpusim->g_the_gpu->hit_watchpoint(i->first,thd,pI); } } } diff --git a/src/cuda-sim/ptx-stats.cc b/src/cuda-sim/ptx-stats.cc index 0a9f08d..22517df 100644 --- a/src/cuda-sim/ptx-stats.cc +++ b/src/cuda-sim/ptx-stats.cc @@ -32,12 +32,9 @@ #include <stdio.h> #include <map> #include "../tr1_hash_map.h" +#include "../../libcuda/gpgpu_context.h" -// options -bool enable_ptx_file_line_stats; -char * ptx_line_stats_filename = NULL; - -void ptx_file_line_stats_options(option_parser_t opp) +void ptx_stats::ptx_file_line_stats_options(option_parser_t opp) { option_parser_register(opp, "-enable_ptx_file_line_stats", OPT_BOOL, &enable_ptx_file_line_stats, @@ -118,7 +115,7 @@ typedef tr1_hash_map<ptx_file_line, ptx_file_line_stats, hash_ptx_file_line> ptx static ptx_file_line_stats_map_t ptx_file_line_stats_tracker; // output statistics to a file -void ptx_file_line_stats_write_file() +void ptx_stats::ptx_file_line_stats_write_file() { // check if stat collection is turned on if (enable_ptx_file_line_stats == 0) return; @@ -154,27 +151,27 @@ void ptx_file_line_stats_add_exec_count(const ptx_instruction *pInsn) // attribute pipeline latency to this ptx instruction (specified by the pc) // pipeline latency is the number of cycles a warp with this instruction spent in the pipeline -void ptx_file_line_stats_add_latency(unsigned pc, unsigned latency) +void ptx_stats::ptx_file_line_stats_add_latency(unsigned pc, unsigned latency) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())].latency += latency; } // attribute dram traffic to this ptx instruction (specified by the pc) // dram traffic is counted in number of requests -void ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_traffic) +void ptx_stats::ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_traffic) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())].dram_traffic += dram_traffic; } // attribute the number of shared memory access cycles to a ptx instruction // counts both the number of warps doing shared memory access and the number of cycles involved -void ptx_file_line_stats_add_smem_bank_conflict(unsigned pc, unsigned n_way_bkconflict) +void ptx_stats::ptx_file_line_stats_add_smem_bank_conflict(unsigned pc, unsigned n_way_bkconflict) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; line_stats.smem_n_way_bank_conflict_total += n_way_bkconflict; @@ -183,9 +180,9 @@ void ptx_file_line_stats_add_smem_bank_conflict(unsigned pc, unsigned n_way_bkco // attribute a non-coalesced mem access to a ptx instruction // counts both the number of warps causing this and the number of memory requests generated -void ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n_access) +void ptx_stats::ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n_access) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; line_stats.gmem_n_access_total += n_access; @@ -242,17 +239,17 @@ void ptx_file_line_stats_create_exposed_latency_tracker(int n_shader_cores) } // add an inflight memory instruction -void ptx_file_line_stats_add_inflight_memory_insn(int sc_id, unsigned pc) +void ptx_stats::ptx_file_line_stats_add_inflight_memory_insn(int sc_id, unsigned pc) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); inflight_mem_tracker[sc_id].add_count(pInsn); } // remove an inflight memory instruction -void ptx_file_line_stats_sub_inflight_memory_insn(int sc_id, unsigned pc) +void ptx_stats::ptx_file_line_stats_sub_inflight_memory_insn(int sc_id, unsigned pc) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); inflight_mem_tracker[sc_id].sub_count(pInsn); } @@ -265,9 +262,9 @@ void ptx_file_line_stats_commit_exposed_latency(int sc_id, int exposed_latency) } // attribute the number of warp divergence to a ptx instruction -void ptx_file_line_stats_add_warp_divergence(unsigned pc, unsigned n_way_divergence) +void ptx_stats::ptx_file_line_stats_add_warp_divergence(unsigned pc, unsigned n_way_divergence) { - const ptx_instruction *pInsn = function_info::pc_to_instruction(pc); + const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; line_stats.warp_divergence += n_way_divergence; diff --git a/src/cuda-sim/ptx-stats.h b/src/cuda-sim/ptx-stats.h index 4fc6599..246b4ce 100644 --- a/src/cuda-sim/ptx-stats.h +++ b/src/cuda-sim/ptx-stats.h @@ -29,13 +29,6 @@ #include "../option_parser.h" -extern bool enable_ptx_file_line_stats; - -// set options -void ptx_file_line_stats_options(option_parser_t opp); - -// output stats to a file -void ptx_file_line_stats_write_file(); #ifdef __cplusplus // stat collection interface to cuda-sim @@ -44,15 +37,32 @@ void ptx_file_line_stats_add_exec_count(const ptx_instruction *pInsn); #endif // stat collection interface to gpgpu-sim -void ptx_file_line_stats_add_latency(unsigned pc, unsigned latency); -void ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_traffic); -void ptx_file_line_stats_add_smem_bank_conflict(unsigned pc, unsigned n_way_bkconflict); -void ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n_access); void ptx_file_line_stats_create_exposed_latency_tracker(int n_shader_cores); -void ptx_file_line_stats_add_inflight_memory_insn(int sc_id, unsigned pc); -void ptx_file_line_stats_sub_inflight_memory_insn(int sc_id, unsigned pc); void ptx_file_line_stats_commit_exposed_latency(int sc_id, int exposed_latency); -void ptx_file_line_stats_add_warp_divergence(unsigned pc, unsigned n_way_divergence); +class gpgpu_context; +class ptx_stats { + public: + ptx_stats(gpgpu_context* ctx) { + ptx_line_stats_filename = NULL; + gpgpu_ctx = ctx; + } + char * ptx_line_stats_filename; + bool enable_ptx_file_line_stats; + gpgpu_context* gpgpu_ctx; + // set options + void ptx_file_line_stats_options(option_parser_t opp); + + // output stats to a file + void ptx_file_line_stats_write_file(); + // stat collection interface to gpgpu-sim + void ptx_file_line_stats_add_latency(unsigned pc, unsigned latency); + void ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_traffic); + void ptx_file_line_stats_add_smem_bank_conflict(unsigned pc, unsigned n_way_bkconflict); + void ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n_access); + void ptx_file_line_stats_add_inflight_memory_insn(int sc_id, unsigned pc); + void ptx_file_line_stats_sub_inflight_memory_insn(int sc_id, unsigned pc); + void ptx_file_line_stats_add_warp_divergence(unsigned pc, unsigned n_way_divergence); +}; diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 36a8a4d..2dadda4 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -31,21 +31,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %option noyywrap %option yylineno %option prefix="ptx_" + +%option bison-bridge +%option reentrant + %{ #include "opcodes.h" +#include "ptx_parser.h" #include "ptx.tab.h" #include <string.h> +#include "../../libcuda/gpgpu_context.h" -#define LINEBUF_SIZE (64*1024) -char linebuf[LINEBUF_SIZE]; -unsigned col = 0; -#define TC col+=strlen(ptx_text); +#define LINEBUF_SIZE (4*1024) +#define TC recognizer->col+=strlen(yytext); #define CHECK_UNSIGNED \ if( yytext[strlen(yytext)-1]=='U' ) { \ printf("GPGPU-Sim: ERROR ** U modifier not implemented\n"); \ abort(); \ } -int ptx_error( const char *s ); +#define YY_DECL int ptx_lex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner, ptx_recognizer* recognizer) +int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ); %} %s IN_STRING @@ -54,123 +60,124 @@ int ptx_error( const char *s ); %x NOT_OPCODE %% -abs TC; ptx_lval.int_value = ABS_OP; return OPCODE; -add TC; ptx_lval.int_value = ADD_OP; return OPCODE; -addp TC; ptx_lval.int_value = ADDP_OP; return OPCODE; -addc TC; ptx_lval.int_value = ADDC_OP; return OPCODE; -and TC; ptx_lval.int_value = AND_OP; return OPCODE; -andn TC; ptx_lval.int_value = ANDN_OP; return OPCODE; -atom TC; ptx_lval.int_value = ATOM_OP; return OPCODE; -bar.warp TC; ptx_lval.int_value = NOP_OP; return OPCODE; -bar TC; ptx_lval.int_value = BAR_OP; return OPCODE; -bfe TC; ptx_lval.int_value = BFE_OP; return OPCODE; -bfi TC; ptx_lval.int_value = BFI_OP; return OPCODE; -bfind TC; ptx_lval.int_value = BFIND_OP; return OPCODE; -bra TC; ptx_lval.int_value = BRA_OP; return OPCODE; -brx TC; ptx_lval.int_value = BRX_OP; return OPCODE; -brev TC; ptx_lval.int_value = BREV_OP; return OPCODE; -brkpt TC; ptx_lval.int_value = BRKPT_OP; return OPCODE; +abs TC; yylval->int_value = ABS_OP; return OPCODE; +add TC; yylval->int_value = ADD_OP; return OPCODE; +addp TC; yylval->int_value = ADDP_OP; return OPCODE; +addc TC; yylval->int_value = ADDC_OP; return OPCODE; +and TC; yylval->int_value = AND_OP; return OPCODE; +andn TC; yylval->int_value = ANDN_OP; return OPCODE; +atom TC; yylval->int_value = ATOM_OP; return OPCODE; +bar.warp TC; yylval->int_value = NOP_OP; return OPCODE; +bar TC; yylval->int_value = BAR_OP; return OPCODE; +bfe TC; yylval->int_value = BFE_OP; return OPCODE; +bfi TC; yylval->int_value = BFI_OP; return OPCODE; +bfind TC; yylval->int_value = BFIND_OP; return OPCODE; +bra TC; yylval->int_value = BRA_OP; return OPCODE; +brx TC; yylval->int_value = BRX_OP; return OPCODE; +brev TC; yylval->int_value = BREV_OP; return OPCODE; +brkpt TC; yylval->int_value = BRKPT_OP; return OPCODE; -wmma TC; ptx_lval.int_value = MMA_OP; return OPCODE; -wmma\.load TC; ptx_lval.int_value = MMA_LD_OP; return OPCODE; -wmma\.store TC; ptx_lval.int_value = MMA_ST_OP; return OPCODE; +wmma TC; yylval->int_value = MMA_OP; return OPCODE; +wmma\.load TC; yylval->int_value = MMA_LD_OP; return OPCODE; +wmma\.store TC; yylval->int_value = MMA_ST_OP; return OPCODE; -call TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALL_OP; return OPCODE; // blocking opcode token in case the callee has the same name as an opcode -callp TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALLP_OP; return OPCODE; -clz TC; ptx_lval.int_value = CLZ_OP; return OPCODE; -cnot TC; ptx_lval.int_value = CNOT_OP; return OPCODE; -cos TC; ptx_lval.int_value = COS_OP; return OPCODE; -cvt TC; ptx_lval.int_value = CVT_OP; return OPCODE; -cvta TC; ptx_lval.int_value = CVTA_OP; return OPCODE; -div TC; ptx_lval.int_value = DIV_OP; return OPCODE; -dp4a TC; ptx_lval.int_value = DP4A_OP; return OPCODE; -ex2 TC; ptx_lval.int_value = EX2_OP; return OPCODE; -exit TC; ptx_lval.int_value = EXIT_OP; return OPCODE; -fma TC; ptx_lval.int_value = FMA_OP; return OPCODE; -isspacep TC; ptx_lval.int_value = ISSPACEP_OP; return OPCODE; -ld TC; ptx_lval.int_value = LD_OP; return OPCODE; -ld.volatile TC; ptx_lval.int_value = LD_OP; return OPCODE; -ldu TC; ptx_lval.int_value = LDU_OP; return OPCODE; -lg2 TC; ptx_lval.int_value = LG2_OP; return OPCODE; -mad24 TC; ptx_lval.int_value = MAD24_OP; return OPCODE; -mad TC; ptx_lval.int_value = MAD_OP; return OPCODE; -madc TC; ptx_lval.int_value = MADC_OP; return OPCODE; -madp TC; ptx_lval.int_value = MADP_OP; return OPCODE; -max TC; ptx_lval.int_value = MAX_OP; return OPCODE; -membar TC; ptx_lval.int_value = MEMBAR_OP; return OPCODE; -min TC; ptx_lval.int_value = MIN_OP; return OPCODE; -mov TC; ptx_lval.int_value = MOV_OP; return OPCODE; -mul24 TC; ptx_lval.int_value = MUL24_OP; return OPCODE; -mul TC; ptx_lval.int_value = MUL_OP; return OPCODE; -neg TC; ptx_lval.int_value = NEG_OP; return OPCODE; -nandn TC; ptx_lval.int_value = NANDN_OP; return OPCODE; -norn TC; ptx_lval.int_value = NORN_OP; return OPCODE; -not TC; ptx_lval.int_value = NOT_OP; return OPCODE; -or TC; ptx_lval.int_value = OR_OP; return OPCODE; -orn TC; ptx_lval.int_value = ORN_OP; return OPCODE; -pmevent TC; ptx_lval.int_value = PMEVENT_OP; return OPCODE; -popc TC; ptx_lval.int_value = POPC_OP; return OPCODE; -prefetch TC; ptx_lval.int_value = PREFETCH_OP; return OPCODE; -prefetchu TC; ptx_lval.int_value = PREFETCHU_OP; return OPCODE; -prmt TC; ptx_lval.int_value = PRMT_OP; return OPCODE; -rcp TC; ptx_lval.int_value = RCP_OP; return OPCODE; -red TC; ptx_lval.int_value = RED_OP; return OPCODE; -rem TC; ptx_lval.int_value = REM_OP; return OPCODE; -ret TC; ptx_lval.int_value = RET_OP; return OPCODE; -retp TC; ptx_lval.int_value = RETP_OP; return OPCODE; -rsqrt TC; ptx_lval.int_value = RSQRT_OP; return OPCODE; -sad TC; ptx_lval.int_value = SAD_OP; return OPCODE; -selp TC; ptx_lval.int_value = SELP_OP; return OPCODE; -setp TC; ptx_lval.int_value = SETP_OP; return OPCODE; -set TC; ptx_lval.int_value = SET_OP; return OPCODE; -shfl TC; ptx_lval.int_value = SHFL_OP; return OPCODE; -shl TC; ptx_lval.int_value = SHL_OP; return OPCODE; -shr TC; ptx_lval.int_value = SHR_OP; return OPCODE; -sin TC; ptx_lval.int_value = SIN_OP; return OPCODE; -slct TC; ptx_lval.int_value = SLCT_OP; return OPCODE; -sqrt TC; ptx_lval.int_value = SQRT_OP; return OPCODE; -sst TC; ptx_lval.int_value = SST_OP; return OPCODE; -ssy TC; ptx_lval.int_value = SSY_OP; return OPCODE; -st TC; ptx_lval.int_value = ST_OP; return OPCODE; -st.volatile TC; ptx_lval.int_value = ST_OP; return OPCODE; -sub TC; ptx_lval.int_value = SUB_OP; return OPCODE; -subc TC; ptx_lval.int_value = SUBC_OP; return OPCODE; -suld TC; ptx_lval.int_value = SULD_OP; return OPCODE; -sured TC; ptx_lval.int_value = SURED_OP; return OPCODE; -surst TC; ptx_lval.int_value = SUST_OP; return OPCODE; -suq TC; ptx_lval.int_value = SUQ_OP; return OPCODE; -tex TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = TEX_OP; return OPCODE; -txq TC; ptx_lval.int_value = TEX_OP; return OPCODE; -trap TC; ptx_lval.int_value = TRAP_OP; return OPCODE; -vabsdiff TC; ptx_lval.int_value = VABSDIFF_OP; return OPCODE; -vadd TC; ptx_lval.int_value = VADD_OP; return OPCODE; -vmad TC; ptx_lval.int_value = VMAD_OP; return OPCODE; -vmax TC; ptx_lval.int_value = VMAX_OP; return OPCODE; -vmin TC; ptx_lval.int_value = VMIN_OP; return OPCODE; -vset TC; ptx_lval.int_value = VSET_OP; return OPCODE; -vshl TC; ptx_lval.int_value = VSHL_OP; return OPCODE; -vshr TC; ptx_lval.int_value = VSHR_OP; return OPCODE; -vsub TC; ptx_lval.int_value = VSUB_OP; return OPCODE; -vote TC; ptx_lval.int_value = VOTE_OP; return OPCODE; -xor TC; ptx_lval.int_value = XOR_OP; return OPCODE; -nop TC; ptx_lval.int_value = NOP_OP; return OPCODE; -break TC; ptx_lval.int_value = BREAK_OP; return OPCODE; -breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; +call TC; BEGIN(NOT_OPCODE); yylval->int_value = CALL_OP; return OPCODE; // blocking opcode token in case the callee has the same name as an opcode +callp TC; BEGIN(NOT_OPCODE); yylval->int_value = CALLP_OP; return OPCODE; +clz TC; yylval->int_value = CLZ_OP; return OPCODE; +cnot TC; yylval->int_value = CNOT_OP; return OPCODE; +cos TC; yylval->int_value = COS_OP; return OPCODE; +cvt TC; yylval->int_value = CVT_OP; return OPCODE; +cvta TC; yylval->int_value = CVTA_OP; return OPCODE; +div TC; yylval->int_value = DIV_OP; return OPCODE; +dp4a TC; yylval->int_value = DP4A_OP; return OPCODE; +ex2 TC; yylval->int_value = EX2_OP; return OPCODE; +exit TC; yylval->int_value = EXIT_OP; return OPCODE; +fma TC; yylval->int_value = FMA_OP; return OPCODE; +isspacep TC; yylval->int_value = ISSPACEP_OP; return OPCODE; +ld TC; yylval->int_value = LD_OP; return OPCODE; +ld.volatile TC; yylval->int_value = LD_OP; return OPCODE; +ldu TC; yylval->int_value = LDU_OP; return OPCODE; +lg2 TC; yylval->int_value = LG2_OP; return OPCODE; +mad24 TC; yylval->int_value = MAD24_OP; return OPCODE; +mad TC; yylval->int_value = MAD_OP; return OPCODE; +madc TC; yylval->int_value = MADC_OP; return OPCODE; +madp TC; yylval->int_value = MADP_OP; return OPCODE; +max TC; yylval->int_value = MAX_OP; return OPCODE; +membar TC; yylval->int_value = MEMBAR_OP; return OPCODE; +min TC; yylval->int_value = MIN_OP; return OPCODE; +mov TC; yylval->int_value = MOV_OP; return OPCODE; +mul24 TC; yylval->int_value = MUL24_OP; return OPCODE; +mul TC; yylval->int_value = MUL_OP; return OPCODE; +neg TC; yylval->int_value = NEG_OP; return OPCODE; +nandn TC; yylval->int_value = NANDN_OP; return OPCODE; +norn TC; yylval->int_value = NORN_OP; return OPCODE; +not TC; yylval->int_value = NOT_OP; return OPCODE; +or TC; yylval->int_value = OR_OP; return OPCODE; +orn TC; yylval->int_value = ORN_OP; return OPCODE; +pmevent TC; yylval->int_value = PMEVENT_OP; return OPCODE; +popc TC; yylval->int_value = POPC_OP; return OPCODE; +prefetch TC; yylval->int_value = PREFETCH_OP; return OPCODE; +prefetchu TC; yylval->int_value = PREFETCHU_OP; return OPCODE; +prmt TC; yylval->int_value = PRMT_OP; return OPCODE; +rcp TC; yylval->int_value = RCP_OP; return OPCODE; +red TC; yylval->int_value = RED_OP; return OPCODE; +rem TC; yylval->int_value = REM_OP; return OPCODE; +ret TC; yylval->int_value = RET_OP; return OPCODE; +retp TC; yylval->int_value = RETP_OP; return OPCODE; +rsqrt TC; yylval->int_value = RSQRT_OP; return OPCODE; +sad TC; yylval->int_value = SAD_OP; return OPCODE; +selp TC; yylval->int_value = SELP_OP; return OPCODE; +setp TC; yylval->int_value = SETP_OP; return OPCODE; +set TC; yylval->int_value = SET_OP; return OPCODE; +shfl TC; yylval->int_value = SHFL_OP; return OPCODE; +shl TC; yylval->int_value = SHL_OP; return OPCODE; +shr TC; yylval->int_value = SHR_OP; return OPCODE; +sin TC; yylval->int_value = SIN_OP; return OPCODE; +slct TC; yylval->int_value = SLCT_OP; return OPCODE; +sqrt TC; yylval->int_value = SQRT_OP; return OPCODE; +sst TC; yylval->int_value = SST_OP; return OPCODE; +ssy TC; yylval->int_value = SSY_OP; return OPCODE; +st TC; yylval->int_value = ST_OP; return OPCODE; +st.volatile TC; yylval->int_value = ST_OP; return OPCODE; +sub TC; yylval->int_value = SUB_OP; return OPCODE; +subc TC; yylval->int_value = SUBC_OP; return OPCODE; +suld TC; yylval->int_value = SULD_OP; return OPCODE; +sured TC; yylval->int_value = SURED_OP; return OPCODE; +surst TC; yylval->int_value = SUST_OP; return OPCODE; +suq TC; yylval->int_value = SUQ_OP; return OPCODE; +tex TC; BEGIN(NOT_OPCODE); yylval->int_value = TEX_OP; return OPCODE; +txq TC; yylval->int_value = TEX_OP; return OPCODE; +trap TC; yylval->int_value = TRAP_OP; return OPCODE; +vabsdiff TC; yylval->int_value = VABSDIFF_OP; return OPCODE; +vadd TC; yylval->int_value = VADD_OP; return OPCODE; +vmad TC; yylval->int_value = VMAD_OP; return OPCODE; +vmax TC; yylval->int_value = VMAX_OP; return OPCODE; +vmin TC; yylval->int_value = VMIN_OP; return OPCODE; +vset TC; yylval->int_value = VSET_OP; return OPCODE; +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; +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; +breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE; "CPTX_END" printf("ENDING CUSTOM PTX.\n"); BEGIN(IN_COMMENT); <INITIAL,NOT_OPCODE,IN_INST,IN_FUNC_DECL>{ -\.a\.sync TC; ptx_lval.int_value = LOAD_A; return WMMA_DIRECTIVE; -\.b\.sync TC; ptx_lval.int_value = LOAD_B; return WMMA_DIRECTIVE; -\.c\.sync TC; ptx_lval.int_value = LOAD_C; return WMMA_DIRECTIVE; -\.d\.sync TC; ptx_lval.int_value = STORE_D; return WMMA_DIRECTIVE; -\.mma\.sync TC;ptx_lval.int_value=MMA; return WMMA_DIRECTIVE; +\.a\.sync TC; yylval->int_value = LOAD_A; return WMMA_DIRECTIVE; +\.b\.sync TC; yylval->int_value = LOAD_B; return WMMA_DIRECTIVE; +\.c\.sync TC; yylval->int_value = LOAD_C; return WMMA_DIRECTIVE; +\.d\.sync TC; yylval->int_value = STORE_D; return WMMA_DIRECTIVE; +\.mma\.sync TC;yylval->int_value=MMA; return WMMA_DIRECTIVE; + +\.row TC; yylval->int_value = ROW; return LAYOUT; +\.col TC; yylval->int_value = COL; return LAYOUT; +\.m16n16k16 TC; yylval->int_value = M16N16K16; return CONFIGURATION; +\.m32n8k16 TC; yylval->int_value = M32N8K16; return CONFIGURATION; +\.m8n32k16 TC; yylval->int_value = M8N32K16; return CONFIGURATION; -\.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; -\.m32n8k16 TC; ptx_lval.int_value = M32N8K16; return CONFIGURATION; -\.m8n32k16 TC; ptx_lval.int_value = M8N32K16; return CONFIGURATION; \.f4e TC; return PRMT_F4E_MODE; \.b4e TC; return PRMT_B4E_MODE; \.rc8 TC; return PRMT_RC8_MODE; @@ -183,8 +190,8 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; \.byte TC; return BYTE_DIRECTIVE; /* not in PTX 2.1 */ \.callprototype TC; return CALLPROTOTYPE_DIRECTIVE; \.calltargets TC; return CALLTARGETS_DIRECTIVE; -\.const\[[0-9]+\] TC; ptx_lval.int_value = atoi(yytext+7); return CONST_DIRECTIVE; -\.const TC; ptx_lval.int_value = 0; return CONST_DIRECTIVE; +\.const\[[0-9]+\] TC; yylval->int_value = atoi(yytext+7); return CONST_DIRECTIVE; +\.const TC; yylval->int_value = 0; return CONST_DIRECTIVE; \.entry TC; return ENTRY_DIRECTIVE; \.extern TC; return EXTERN_DIRECTIVE; \.file TC; BEGIN(INITIAL); return FILE_DIRECTIVE; @@ -219,40 +226,40 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; \.constptr TC; return CONSTPTR_DIRECTIVE; /* Ptx plus directive for pointer to constant memory */ \.ptr TC; return PTR_DIRECTIVE; /* Added for new OpenCL genrated code */ -"%clock" TC; ptx_lval.int_value = CLOCK_REG; return SPECIAL_REGISTER; -"%halfclock" TC; ptx_lval.int_value = HALFCLOCK_ID; return SPECIAL_REGISTER; -"%clock64" TC; ptx_lval.int_value = CLOCK64_REG; return SPECIAL_REGISTER; -"%ctaid" TC; ptx_lval.int_value = CTAID_REG; return SPECIAL_REGISTER; -"%envreg"[0-9]+ TC; sscanf(yytext+7,"%u",&ptx_lval.int_value); ptx_lval.int_value<<=16; ptx_lval.int_value += ENVREG_REG; return SPECIAL_REGISTER; -"%gridid" TC; ptx_lval.int_value = GRIDID_REG; return SPECIAL_REGISTER; -"%laneid" TC; ptx_lval.int_value = LANEID_REG; return SPECIAL_REGISTER; -"%lanemask_eq" TC; ptx_lval.int_value = LANEMASK_EQ_REG; return SPECIAL_REGISTER; -"%lanemask_le" TC; ptx_lval.int_value = LANEMASK_LE_REG; return SPECIAL_REGISTER; -"%lanemask_lt" TC; ptx_lval.int_value = LANEMASK_LT_REG; return SPECIAL_REGISTER; -"%lanemask_ge" TC; ptx_lval.int_value = LANEMASK_GE_REG; return SPECIAL_REGISTER; -"%lanemask_gt" TC; ptx_lval.int_value = LANEMASK_GT_REG; return SPECIAL_REGISTER; -"%nctaid" TC; ptx_lval.int_value = NCTAID_REG; return SPECIAL_REGISTER; -"%ntid" TC; ptx_lval.int_value = NTID_REG; return SPECIAL_REGISTER; -"%nsmid" TC; ptx_lval.int_value = NSMID_REG; return SPECIAL_REGISTER; -"%nwarpid" TC; ptx_lval.int_value = NWARPID_REG; return SPECIAL_REGISTER; -"%pm"[0-3] TC; sscanf(yytext+3,"%u",&ptx_lval.int_value); ptx_lval.int_value<<=16; ptx_lval.int_value += PM_REG; return SPECIAL_REGISTER; -"%smid" TC; ptx_lval.int_value = SMID_REG; return SPECIAL_REGISTER; -"%tid" TC; ptx_lval.int_value = TID_REG; return SPECIAL_REGISTER; -"%warpid" TC; ptx_lval.int_value = WARPID_REG; return SPECIAL_REGISTER; -"WARP_SZ" TC; ptx_lval.int_value = WARPSZ_REG; return SPECIAL_REGISTER; +"%clock" TC; yylval->int_value = CLOCK_REG; return SPECIAL_REGISTER; +"%halfclock" TC; yylval->int_value = HALFCLOCK_ID; return SPECIAL_REGISTER; +"%clock64" TC; yylval->int_value = CLOCK64_REG; return SPECIAL_REGISTER; +"%ctaid" TC; yylval->int_value = CTAID_REG; return SPECIAL_REGISTER; +"%envreg"[0-9]+ TC; sscanf(yytext+7,"%u",&yylval->int_value); yylval->int_value<<=16; yylval->int_value += ENVREG_REG; return SPECIAL_REGISTER; +"%gridid" TC; yylval->int_value = GRIDID_REG; return SPECIAL_REGISTER; +"%laneid" TC; yylval->int_value = LANEID_REG; return SPECIAL_REGISTER; +"%lanemask_eq" TC; yylval->int_value = LANEMASK_EQ_REG; return SPECIAL_REGISTER; +"%lanemask_le" TC; yylval->int_value = LANEMASK_LE_REG; return SPECIAL_REGISTER; +"%lanemask_lt" TC; yylval->int_value = LANEMASK_LT_REG; return SPECIAL_REGISTER; +"%lanemask_ge" TC; yylval->int_value = LANEMASK_GE_REG; return SPECIAL_REGISTER; +"%lanemask_gt" TC; yylval->int_value = LANEMASK_GT_REG; return SPECIAL_REGISTER; +"%nctaid" TC; yylval->int_value = NCTAID_REG; return SPECIAL_REGISTER; +"%ntid" TC; yylval->int_value = NTID_REG; return SPECIAL_REGISTER; +"%nsmid" TC; yylval->int_value = NSMID_REG; return SPECIAL_REGISTER; +"%nwarpid" TC; yylval->int_value = NWARPID_REG; return SPECIAL_REGISTER; +"%pm"[0-3] TC; sscanf(yytext+3,"%u",&yylval->int_value); yylval->int_value<<=16; yylval->int_value += PM_REG; return SPECIAL_REGISTER; +"%smid" TC; yylval->int_value = SMID_REG; return SPECIAL_REGISTER; +"%tid" TC; yylval->int_value = TID_REG; return SPECIAL_REGISTER; +"%warpid" TC; yylval->int_value = WARPID_REG; return SPECIAL_REGISTER; +"WARP_SZ" TC; yylval->int_value = WARPSZ_REG; return SPECIAL_REGISTER; -[a-zA-Z_][a-zA-Z0-9_$]* TC; ptx_lval.string_value = strdup(yytext); return IDENTIFIER; -[$%][a-zA-Z0-9_$]+ TC; ptx_lval.string_value = strdup(yytext); return IDENTIFIER; +[a-zA-Z_][a-zA-Z0-9_$]* TC; yylval->string_value = strdup(yytext); return IDENTIFIER; +[$%][a-zA-Z0-9_$]+ TC; yylval->string_value = strdup(yytext); return IDENTIFIER; -[0-9]+\.[0-9]+ TC; sscanf(yytext,"%lf", &ptx_lval.double_value); return DOUBLE_OPERAND; +[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", &ptx_lval.int_value); return INT_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; -[-]?[0-9]+U? TC; CHECK_UNSIGNED; ptx_lval.int_value = atoi(yytext); return INT_OPERAND; +[-]?[0-9]+U? TC; CHECK_UNSIGNED; yylval->int_value = atoi(yytext); return INT_OPERAND; -0[fF][0-9a-fA-F]{8} TC; sscanf(yytext+2,"%x", (unsigned*)(void*)&ptx_lval.float_value); return FLOAT_OPERAND; -0[dD][0-9a-fA-F]{16} TC; sscanf(yytext+2,"%Lx", (unsigned long long*)(void*)&ptx_lval.double_value); return DOUBLE_OPERAND; +0[fF][0-9a-fA-F]{8} TC; sscanf(yytext+2,"%x", (unsigned*)(void*)&yylval->float_value); return FLOAT_OPERAND; +0[dD][0-9a-fA-F]{16} TC; sscanf(yytext+2,"%Lx", (unsigned long long*)(void*)&yylval->double_value); return DOUBLE_OPERAND; \.s8 TC; return S8_TYPE; \.s16 TC; return S16_TYPE; @@ -385,12 +392,12 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; \.2d TC; return GEOM_MODIFIER_2D; \.3d TC; return GEOM_MODIFIER_3D; -\.0 TC; ptx_lval.int_value = 0; return DIMENSION_MODIFIER; -\.1 TC; ptx_lval.int_value = 1; return DIMENSION_MODIFIER; -\.2 TC; ptx_lval.int_value = 2; return DIMENSION_MODIFIER; -\.x TC; ptx_lval.int_value = 0; return DIMENSION_MODIFIER; -\.y TC; ptx_lval.int_value = 1; return DIMENSION_MODIFIER; -\.z TC; ptx_lval.int_value = 2; return DIMENSION_MODIFIER; +\.0 TC; yylval->int_value = 0; return DIMENSION_MODIFIER; +\.1 TC; yylval->int_value = 1; return DIMENSION_MODIFIER; +\.2 TC; yylval->int_value = 2; return DIMENSION_MODIFIER; +\.x TC; yylval->int_value = 0; return DIMENSION_MODIFIER; +\.y TC; yylval->int_value = 1; return DIMENSION_MODIFIER; +\.z TC; yylval->int_value = 2; return DIMENSION_MODIFIER; "-" TC; return MINUS; "+" TC; return PLUS; @@ -413,7 +420,7 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; "//"[^\n]* TC; // eat single -\n.* col=0; strncpy(linebuf, yytext + 1, LINEBUF_SIZE); yyless( 1 ); +\n.* recognizer->col=0; strncpy(recognizer->linebuf, yytext + 1, LINEBUF_SIZE); yyless( 1 ); " " TC; "\t" TC; @@ -441,28 +448,26 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE; } <IN_STRING>{ "\"" TC; BEGIN(INITIAL); return STRING; -[^\"]* TC; ptx_lval.string_value = strdup(yytext); +[^\"]* TC; yylval->string_value = strdup(yytext); } <*>\t@@DWARF.*\n -<INITIAL,NOT_OPCODE,IN_FUNC_DECL>. TC; ptx_error((const char*)NULL); +<INITIAL,NOT_OPCODE,IN_FUNC_DECL>. TC; ptx_error(yyscanner, recognizer, (const char*)NULL); %% -extern int g_error_detected; -extern const char *g_filename; - -int ptx_error( const char *s ) +int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; int i; - g_error_detected = 1; + recognizer->g_error_detected = 1; fflush(stdout); if( s != NULL ) - printf("%s:%u: Syntax error:\n\n", g_filename, ptx_lineno ); - printf(" %s\n", linebuf ); + printf("%s:%u Syntax error:\n\n", recognizer->gpgpu_ctx->g_filename, yylineno ); + printf(" %s\n", recognizer->linebuf ); printf(" "); - for( i=0; i < col-1; i++ ) { - if( linebuf[i] == '\t' ) printf("\t"); + for( i=0; i < recognizer->col-1; i++ ) { + if( recognizer->linebuf[i] == '\t' ) printf("\t"); else printf(" "); } diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y index 45392fb..a01c3c6 100644 --- a/src/cuda-sim/ptx.y +++ b/src/cuda-sim/ptx.y @@ -27,6 +27,18 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +%{ +typedef void * yyscan_t; +class ptx_recognizer; +#include "../../libcuda/gpgpu_context.h" +%} + +%define api.pure full +%parse-param {yyscan_t scanner} +%parse-param {ptx_recognizer* recognizer} +%lex-param {yyscan_t scanner} +%lex-param {ptx_recognizer* recognizer} + %union { double double_value; float float_value; @@ -217,10 +229,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <stdlib.h> #include <string.h> #include <math.h> - void syntax_not_implemented(); - extern int g_func_decl; - int ptx_lex(void); - int ptx_error(const char *); + void syntax_not_implemented(yyscan_t yyscanner, ptx_recognizer* recognizer); + int ptx_lex(YYSTYPE * yylval_param, yyscan_t yyscanner, ptx_recognizer* recognizer); + int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ); %} %% @@ -231,96 +242,96 @@ input: /* empty */ | input function_decl ; -function_defn: function_decl { set_symtab($1); func_header(".skip"); } statement_block { end_function(); } - | function_decl { set_symtab($1); } block_spec_list { func_header(".skip"); } statement_block { end_function(); } +function_defn: function_decl { recognizer->set_symtab($1); recognizer->func_header(".skip"); } statement_block { recognizer->end_function(); } + | function_decl { recognizer->set_symtab($1); } block_spec_list { recognizer->func_header(".skip"); } statement_block { recognizer->end_function(); } ; -block_spec: MAXNTID_DIRECTIVE INT_OPERAND COMMA INT_OPERAND COMMA INT_OPERAND {func_header_info_int(".maxntid", $2); - func_header_info_int(",", $4); - func_header_info_int(",", $6); - maxnt_id($2, $4, $6);} - | MINNCTAPERSM_DIRECTIVE INT_OPERAND { func_header_info_int(".minnctapersm", $2); printf("GPGPU-Sim: Warning: .minnctapersm ignored. \n"); } - | MAXNCTAPERSM_DIRECTIVE INT_OPERAND { func_header_info_int(".maxnctapersm", $2); printf("GPGPU-Sim: Warning: .maxnctapersm ignored. \n"); } +block_spec: MAXNTID_DIRECTIVE INT_OPERAND COMMA INT_OPERAND COMMA INT_OPERAND {recognizer->func_header_info_int(".maxntid", $2); + recognizer->func_header_info_int(",", $4); + recognizer->func_header_info_int(",", $6); + recognizer->maxnt_id($2, $4, $6);} + | MINNCTAPERSM_DIRECTIVE INT_OPERAND { recognizer->func_header_info_int(".minnctapersm", $2); printf("GPGPU-Sim: Warning: .minnctapersm ignored. \n"); } + | MAXNCTAPERSM_DIRECTIVE INT_OPERAND { recognizer->func_header_info_int(".maxnctapersm", $2); printf("GPGPU-Sim: Warning: .maxnctapersm ignored. \n"); } ; block_spec_list: block_spec | block_spec_list block_spec ; -function_decl: function_decl_header LEFT_PAREN { start_function($1); func_header_info("(");} param_entry RIGHT_PAREN {func_header_info(")");} function_ident_param { $$ = reset_symtab(); } - | function_decl_header { start_function($1); } function_ident_param { $$ = reset_symtab(); } - | function_decl_header { start_function($1); add_function_name(""); g_func_decl=0; $$ = reset_symtab(); } +function_decl: function_decl_header LEFT_PAREN { recognizer->start_function($1); recognizer->func_header_info("(");} param_entry RIGHT_PAREN {recognizer->func_header_info(")");} function_ident_param { $$ = recognizer->reset_symtab(); } + | function_decl_header { recognizer->start_function($1); } function_ident_param { $$ = recognizer->reset_symtab(); } + | function_decl_header { recognizer->start_function($1); recognizer->add_function_name(""); recognizer->g_func_decl=0; $$ = recognizer->reset_symtab(); } ; -function_ident_param: IDENTIFIER { add_function_name($1); } LEFT_PAREN {func_header_info("(");} param_list RIGHT_PAREN { g_func_decl=0; func_header_info(")"); } - | IDENTIFIER { add_function_name($1); g_func_decl=0; } +function_ident_param: IDENTIFIER { recognizer->add_function_name($1); } LEFT_PAREN {recognizer->func_header_info("(");} param_list RIGHT_PAREN { recognizer->g_func_decl=0; recognizer->func_header_info(")"); } + | IDENTIFIER { recognizer->add_function_name($1); recognizer->g_func_decl=0; } ; -function_decl_header: ENTRY_DIRECTIVE { $$ = 1; g_func_decl=1; func_header(".entry"); } - | VISIBLE_DIRECTIVE ENTRY_DIRECTIVE { $$ = 1; g_func_decl=1; func_header(".entry"); } - | WEAK_DIRECTIVE ENTRY_DIRECTIVE { $$ = 1; g_func_decl=1; func_header(".entry"); } - | FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } - | VISIBLE_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } - | WEAK_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } - | EXTERN_DIRECTIVE FUNC_DIRECTIVE { $$ = 2; g_func_decl=1; func_header(".func"); } - | WEAK_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; g_func_decl=1; func_header(".func"); } +function_decl_header: ENTRY_DIRECTIVE { $$ = 1; recognizer->g_func_decl=1; recognizer->func_header(".entry"); } + | VISIBLE_DIRECTIVE ENTRY_DIRECTIVE { $$ = 1; recognizer->g_func_decl=1; recognizer->func_header(".entry"); } + | WEAK_DIRECTIVE ENTRY_DIRECTIVE { $$ = 1; recognizer->g_func_decl=1; recognizer->func_header(".entry"); } + | FUNC_DIRECTIVE { $$ = 0; recognizer->g_func_decl=1; recognizer->func_header(".func"); } + | VISIBLE_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; recognizer->g_func_decl=1; recognizer->func_header(".func"); } + | WEAK_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; recognizer->g_func_decl=1; recognizer->func_header(".func"); } + | EXTERN_DIRECTIVE FUNC_DIRECTIVE { $$ = 2; recognizer->g_func_decl=1; recognizer->func_header(".func"); } + | WEAK_DIRECTIVE FUNC_DIRECTIVE { $$ = 0; recognizer->g_func_decl=1; recognizer->func_header(".func"); } ; param_list: /*empty*/ - | param_entry { add_directive(); } - | param_list COMMA {func_header_info(",");} param_entry { add_directive(); } + | param_entry { recognizer->add_directive(); } + | param_list COMMA {recognizer->func_header_info(",");} param_entry { recognizer->add_directive(); } -param_entry: PARAM_DIRECTIVE { add_space_spec(param_space_unclassified,0); } variable_spec ptr_spec identifier_spec { add_function_arg(); } - | REG_DIRECTIVE { add_space_spec(reg_space,0); } variable_spec identifier_spec { add_function_arg(); } +param_entry: PARAM_DIRECTIVE { recognizer->add_space_spec(param_space_unclassified,0); } variable_spec ptr_spec identifier_spec { recognizer->add_function_arg(); } + | REG_DIRECTIVE { recognizer->add_space_spec(reg_space,0); } variable_spec identifier_spec { recognizer->add_function_arg(); } ptr_spec: /*empty*/ | PTR_DIRECTIVE ptr_space_spec ptr_align_spec | PTR_DIRECTIVE ptr_align_spec -ptr_space_spec: GLOBAL_DIRECTIVE { add_ptr_spec(global_space); } - | LOCAL_DIRECTIVE { add_ptr_spec(local_space); } - | SHARED_DIRECTIVE { add_ptr_spec(shared_space); } - | CONST_DIRECTIVE { add_ptr_spec(global_space); } +ptr_space_spec: GLOBAL_DIRECTIVE { recognizer->add_ptr_spec(global_space); } + | LOCAL_DIRECTIVE { recognizer->add_ptr_spec(local_space); } + | SHARED_DIRECTIVE { recognizer->add_ptr_spec(shared_space); } + | CONST_DIRECTIVE { recognizer->add_ptr_spec(global_space); } ptr_align_spec: ALIGN_DIRECTIVE INT_OPERAND statement_block: LEFT_BRACE statement_list RIGHT_BRACE -statement_list: directive_statement { add_directive(); } - | instruction_statement { add_instruction(); } - | statement_list directive_statement { add_directive(); } - | statement_list instruction_statement { add_instruction(); } - | statement_list {start_inst_group();} statement_block {end_inst_group();} - | {start_inst_group();} statement_block {end_inst_group();} +statement_list: directive_statement { recognizer->add_directive(); } + | instruction_statement { recognizer->add_instruction(); } + | statement_list directive_statement { recognizer->add_directive(); } + | statement_list instruction_statement { recognizer->add_instruction(); } + | statement_list {recognizer->start_inst_group();} statement_block {recognizer->end_inst_group();} + | {recognizer->start_inst_group();} statement_block {recognizer->end_inst_group();} ; directive_statement: variable_declaration SEMI_COLON - | VERSION_DIRECTIVE DOUBLE_OPERAND { add_version_info($2, 0); } - | VERSION_DIRECTIVE DOUBLE_OPERAND PLUS { add_version_info($2,1); } + | VERSION_DIRECTIVE DOUBLE_OPERAND { recognizer->add_version_info($2, 0); } + | VERSION_DIRECTIVE DOUBLE_OPERAND PLUS { recognizer->add_version_info($2,1); } | ADDRESS_SIZE_DIRECTIVE INT_OPERAND {/*Do nothing*/} - | TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER { target_header2($2,$4); } - | TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER { target_header3($2,$4,$6); } - | TARGET_DIRECTIVE IDENTIFIER { target_header($2); } - | FILE_DIRECTIVE INT_OPERAND STRING { add_file($2,$3); } - | FILE_DIRECTIVE INT_OPERAND STRING COMMA INT_OPERAND COMMA INT_OPERAND { add_file($2,$3); } + | TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER { recognizer->target_header2($2,$4); } + | TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER { recognizer->target_header3($2,$4,$6); } + | 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 - | PRAGMA_DIRECTIVE STRING SEMI_COLON { add_pragma($2); } + | PRAGMA_DIRECTIVE STRING SEMI_COLON { recognizer->add_pragma($2); } | function_decl SEMI_COLON {/*Do nothing*/} ; -variable_declaration: variable_spec identifier_list { add_variables(); } - | variable_spec identifier_spec EQUALS initializer_list { add_variables(); } - | variable_spec identifier_spec EQUALS literal_operand { add_variables(); } - | CONSTPTR_DIRECTIVE IDENTIFIER COMMA IDENTIFIER COMMA INT_OPERAND { add_constptr($2, $4, $6); } +variable_declaration: variable_spec identifier_list { recognizer->add_variables(); } + | variable_spec identifier_spec EQUALS initializer_list { recognizer->add_variables(); } + | variable_spec identifier_spec EQUALS literal_operand { recognizer->add_variables(); } + | CONSTPTR_DIRECTIVE IDENTIFIER COMMA IDENTIFIER COMMA INT_OPERAND { recognizer->add_constptr($2, $4, $6); } ; -variable_spec: var_spec_list { set_variable_type(); } +variable_spec: var_spec_list { recognizer->set_variable_type(); } identifier_list: identifier_spec | identifier_list COMMA identifier_spec; -identifier_spec: IDENTIFIER { add_identifier($1,0,NON_ARRAY_IDENTIFIER); func_header_info($1);} - | IDENTIFIER LEFT_ANGLE_BRACKET INT_OPERAND RIGHT_ANGLE_BRACKET { func_header_info($1); func_header_info_int("<", $3); func_header_info(">"); +identifier_spec: IDENTIFIER { recognizer->add_identifier($1,0,NON_ARRAY_IDENTIFIER); recognizer->func_header_info($1);} + | IDENTIFIER LEFT_ANGLE_BRACKET INT_OPERAND RIGHT_ANGLE_BRACKET { recognizer->func_header_info($1); recognizer->func_header_info_int("<", $3); recognizer->func_header_info(">"); int i,lbase,l; char *id = NULL; lbase = strlen($1); @@ -328,12 +339,12 @@ identifier_spec: IDENTIFIER { add_identifier($1,0,NON_ARRAY_IDENTIFIER); func_he l = lbase + (int)log10(i+1)+10; id = (char*) malloc(l); snprintf(id,l,"%s%u",$1,i); - add_identifier(id,0,NON_ARRAY_IDENTIFIER); + recognizer->add_identifier(id,0,NON_ARRAY_IDENTIFIER); } free($1); } - | IDENTIFIER LEFT_SQUARE_BRACKET RIGHT_SQUARE_BRACKET { add_identifier($1,0,ARRAY_IDENTIFIER_NO_DIM); func_header_info($1); func_header_info("["); func_header_info("]");} - | IDENTIFIER LEFT_SQUARE_BRACKET INT_OPERAND RIGHT_SQUARE_BRACKET { add_identifier($1,$3,ARRAY_IDENTIFIER); func_header_info($1); func_header_info_int("[",$3); func_header_info("]");} + | IDENTIFIER LEFT_SQUARE_BRACKET RIGHT_SQUARE_BRACKET { recognizer->add_identifier($1,0,ARRAY_IDENTIFIER_NO_DIM); recognizer->func_header_info($1); recognizer->func_header_info("["); recognizer->func_header_info("]");} + | 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 @@ -343,93 +354,93 @@ var_spec: space_spec | type_spec | align_spec | VISIBLE_DIRECTIVE - | EXTERN_DIRECTIVE { add_extern_spec(); } + | EXTERN_DIRECTIVE { recognizer->add_extern_spec(); } | WEAK_DIRECTIVE ; -align_spec: ALIGN_DIRECTIVE INT_OPERAND { add_alignment_spec($2); } +align_spec: ALIGN_DIRECTIVE INT_OPERAND { recognizer->add_alignment_spec($2); } -space_spec: REG_DIRECTIVE { add_space_spec(reg_space,0); } - | SREG_DIRECTIVE { add_space_spec(reg_space,0); } +space_spec: REG_DIRECTIVE { recognizer->add_space_spec(reg_space,0); } + | SREG_DIRECTIVE { recognizer->add_space_spec(reg_space,0); } | addressable_spec ; -addressable_spec: CONST_DIRECTIVE { add_space_spec(const_space,$1); } - | GLOBAL_DIRECTIVE { add_space_spec(global_space,0); } - | LOCAL_DIRECTIVE { add_space_spec(local_space,0); } - | PARAM_DIRECTIVE { add_space_spec(param_space_unclassified,0); } - | SHARED_DIRECTIVE { add_space_spec(shared_space,0); } - | SSTARR_DIRECTIVE { add_space_spec(sstarr_space,0); } - | SURF_DIRECTIVE { add_space_spec(surf_space,0); } - | TEX_DIRECTIVE { add_space_spec(tex_space,0); } +addressable_spec: CONST_DIRECTIVE { recognizer->add_space_spec(const_space,$1); } + | GLOBAL_DIRECTIVE { recognizer->add_space_spec(global_space,0); } + | LOCAL_DIRECTIVE { recognizer->add_space_spec(local_space,0); } + | PARAM_DIRECTIVE { recognizer->add_space_spec(param_space_unclassified,0); } + | SHARED_DIRECTIVE { recognizer->add_space_spec(shared_space,0); } + | SSTARR_DIRECTIVE { recognizer->add_space_spec(sstarr_space,0); } + | SURF_DIRECTIVE { recognizer->add_space_spec(surf_space,0); } + | TEX_DIRECTIVE { recognizer->add_space_spec(tex_space,0); } ; type_spec: scalar_type | vector_spec scalar_type ; -vector_spec: V2_TYPE { add_option(V2_TYPE); func_header_info(".v2");} - | V3_TYPE { add_option(V3_TYPE); func_header_info(".v3");} - | V4_TYPE { add_option(V4_TYPE); func_header_info(".v4");} +vector_spec: V2_TYPE { recognizer->add_option(V2_TYPE); recognizer->func_header_info(".v2");} + | V3_TYPE { recognizer->add_option(V3_TYPE); recognizer->func_header_info(".v3");} + | V4_TYPE { recognizer->add_option(V4_TYPE); recognizer->func_header_info(".v4");} ; -scalar_type: S8_TYPE { add_scalar_type_spec( S8_TYPE ); } - | S16_TYPE { add_scalar_type_spec( S16_TYPE ); } - | S32_TYPE { add_scalar_type_spec( S32_TYPE ); } - | S64_TYPE { add_scalar_type_spec( S64_TYPE ); } - | U8_TYPE { add_scalar_type_spec( U8_TYPE ); } - | U16_TYPE { add_scalar_type_spec( U16_TYPE ); } - | U32_TYPE { add_scalar_type_spec( U32_TYPE ); } - | U64_TYPE { add_scalar_type_spec( U64_TYPE ); } - | F16_TYPE { add_scalar_type_spec( F16_TYPE ); } - | F32_TYPE { add_scalar_type_spec( F32_TYPE ); } - | F64_TYPE { add_scalar_type_spec( F64_TYPE ); } - | FF64_TYPE { add_scalar_type_spec( FF64_TYPE ); } - | B8_TYPE { add_scalar_type_spec( B8_TYPE ); } - | B16_TYPE { add_scalar_type_spec( B16_TYPE ); } - | B32_TYPE { add_scalar_type_spec( B32_TYPE ); } - | B64_TYPE { add_scalar_type_spec( B64_TYPE ); } - | BB64_TYPE { add_scalar_type_spec( BB64_TYPE ); } - | BB128_TYPE { add_scalar_type_spec( BB128_TYPE ); } - | PRED_TYPE { add_scalar_type_spec( PRED_TYPE ); } - | TEXREF_TYPE { add_scalar_type_spec( TEXREF_TYPE ); } - | SAMPLERREF_TYPE { add_scalar_type_spec( SAMPLERREF_TYPE ); } - | SURFREF_TYPE { add_scalar_type_spec( SURFREF_TYPE ); } +scalar_type: S8_TYPE { recognizer->add_scalar_type_spec( S8_TYPE ); } + | S16_TYPE { recognizer->add_scalar_type_spec( S16_TYPE ); } + | S32_TYPE { recognizer->add_scalar_type_spec( S32_TYPE ); } + | S64_TYPE { recognizer->add_scalar_type_spec( S64_TYPE ); } + | U8_TYPE { recognizer->add_scalar_type_spec( U8_TYPE ); } + | U16_TYPE { recognizer->add_scalar_type_spec( U16_TYPE ); } + | U32_TYPE { recognizer->add_scalar_type_spec( U32_TYPE ); } + | U64_TYPE { recognizer->add_scalar_type_spec( U64_TYPE ); } + | F16_TYPE { recognizer->add_scalar_type_spec( F16_TYPE ); } + | F32_TYPE { recognizer->add_scalar_type_spec( F32_TYPE ); } + | F64_TYPE { recognizer->add_scalar_type_spec( F64_TYPE ); } + | FF64_TYPE { recognizer->add_scalar_type_spec( FF64_TYPE ); } + | B8_TYPE { recognizer->add_scalar_type_spec( B8_TYPE ); } + | B16_TYPE { recognizer->add_scalar_type_spec( B16_TYPE ); } + | B32_TYPE { recognizer->add_scalar_type_spec( B32_TYPE ); } + | B64_TYPE { recognizer->add_scalar_type_spec( B64_TYPE ); } + | BB64_TYPE { recognizer->add_scalar_type_spec( BB64_TYPE ); } + | BB128_TYPE { recognizer->add_scalar_type_spec( BB128_TYPE ); } + | PRED_TYPE { recognizer->add_scalar_type_spec( PRED_TYPE ); } + | TEXREF_TYPE { recognizer->add_scalar_type_spec( TEXREF_TYPE ); } + | SAMPLERREF_TYPE { recognizer->add_scalar_type_spec( SAMPLERREF_TYPE ); } + | SURFREF_TYPE { recognizer->add_scalar_type_spec( SURFREF_TYPE ); } ; -initializer_list: LEFT_BRACE literal_list RIGHT_BRACE { add_array_initializer(); } - | LEFT_BRACE initializer_list RIGHT_BRACE { syntax_not_implemented(); } +initializer_list: LEFT_BRACE literal_list RIGHT_BRACE { recognizer->add_array_initializer(); } + | LEFT_BRACE initializer_list RIGHT_BRACE { syntax_not_implemented(scanner, recognizer); } literal_list: literal_operand | literal_list COMMA literal_operand; instruction_statement: instruction SEMI_COLON - | IDENTIFIER COLON { add_label($1); } + | IDENTIFIER COLON { recognizer->add_label($1); } | pred_spec instruction SEMI_COLON; -instruction: opcode_spec LEFT_PAREN operand RIGHT_PAREN { set_return(); } COMMA operand COMMA LEFT_PAREN operand_list RIGHT_PAREN +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 ; -opcode_spec: OPCODE { add_opcode($1); } option_list - | OPCODE { add_opcode($1); } +opcode_spec: OPCODE { recognizer->add_opcode($1); } option_list + | OPCODE { recognizer->add_opcode($1); } -pred_spec: PRED IDENTIFIER { add_pred($2,0, -1); } - | PRED EXCLAMATION IDENTIFIER { add_pred($3,1, -1); } - | PRED IDENTIFIER LT_OPTION { add_pred($2,0,1); } - | PRED IDENTIFIER EQ_OPTION { add_pred($2,0,2); } - | PRED IDENTIFIER LE_OPTION { add_pred($2,0,3); } - | PRED IDENTIFIER NE_OPTION { add_pred($2,0,5); } - | PRED IDENTIFIER GE_OPTION { add_pred($2,0,6); } - | PRED IDENTIFIER EQU_OPTION { add_pred($2,0,10); } - | PRED IDENTIFIER GTU_OPTION { add_pred($2,0,12); } - | PRED IDENTIFIER NEU_OPTION { add_pred($2,0,13); } - | PRED IDENTIFIER CF_OPTION { add_pred($2,0,17); } - | PRED IDENTIFIER SF_OPTION { add_pred($2,0,19); } - | PRED IDENTIFIER NSF_OPTION { add_pred($2,0,28); } +pred_spec: PRED IDENTIFIER { recognizer->add_pred($2,0, -1); } + | PRED EXCLAMATION IDENTIFIER { recognizer->add_pred($3,1, -1); } + | PRED IDENTIFIER LT_OPTION { recognizer->add_pred($2,0,1); } + | PRED IDENTIFIER EQ_OPTION { recognizer->add_pred($2,0,2); } + | PRED IDENTIFIER LE_OPTION { recognizer->add_pred($2,0,3); } + | PRED IDENTIFIER NE_OPTION { recognizer->add_pred($2,0,5); } + | PRED IDENTIFIER GE_OPTION { recognizer->add_pred($2,0,6); } + | PRED IDENTIFIER EQU_OPTION { recognizer->add_pred($2,0,10); } + | PRED IDENTIFIER GTU_OPTION { recognizer->add_pred($2,0,12); } + | PRED IDENTIFIER NEU_OPTION { recognizer->add_pred($2,0,13); } + | PRED IDENTIFIER CF_OPTION { recognizer->add_pred($2,0,17); } + | PRED IDENTIFIER SF_OPTION { recognizer->add_pred($2,0,19); } + | PRED IDENTIFIER NSF_OPTION { recognizer->add_pred($2,0,28); } ; option_list: option @@ -441,108 +452,108 @@ option: type_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); } - | UNI_OPTION { add_option(UNI_OPTION); } - | WIDE_OPTION { add_option(WIDE_OPTION); } - | ANY_OPTION { add_option(ANY_OPTION); } - | ALL_OPTION { add_option(ALL_OPTION); } - | BALLOT_OPTION { add_option(BALLOT_OPTION); } - | GLOBAL_OPTION { add_option(GLOBAL_OPTION); } - | CTA_OPTION { add_option(CTA_OPTION); } - | SYS_OPTION { add_option(SYS_OPTION); } - | GEOM_MODIFIER_1D { add_option(GEOM_MODIFIER_1D); } - | GEOM_MODIFIER_2D { add_option(GEOM_MODIFIER_2D); } - | GEOM_MODIFIER_3D { add_option(GEOM_MODIFIER_3D); } - | SAT_OPTION { add_option(SAT_OPTION); } - | FTZ_OPTION { add_option(FTZ_OPTION); } - | NEG_OPTION { add_option(NEG_OPTION); } - | APPROX_OPTION { add_option(APPROX_OPTION); } - | FULL_OPTION { add_option(FULL_OPTION); } - | EXIT_OPTION { add_option(EXIT_OPTION); } - | ABS_OPTION { add_option(ABS_OPTION); } + | SYNC_OPTION { recognizer->add_option(SYNC_OPTION); } + | ARRIVE_OPTION { recognizer->add_option(ARRIVE_OPTION); } + | RED_OPTION { recognizer->add_option(RED_OPTION); } + | UNI_OPTION { recognizer->add_option(UNI_OPTION); } + | WIDE_OPTION { recognizer->add_option(WIDE_OPTION); } + | ANY_OPTION { recognizer->add_option(ANY_OPTION); } + | ALL_OPTION { recognizer->add_option(ALL_OPTION); } + | BALLOT_OPTION { recognizer->add_option(BALLOT_OPTION); } + | GLOBAL_OPTION { recognizer->add_option(GLOBAL_OPTION); } + | CTA_OPTION { recognizer->add_option(CTA_OPTION); } + | SYS_OPTION { recognizer->add_option(SYS_OPTION); } + | GEOM_MODIFIER_1D { recognizer->add_option(GEOM_MODIFIER_1D); } + | GEOM_MODIFIER_2D { recognizer->add_option(GEOM_MODIFIER_2D); } + | GEOM_MODIFIER_3D { recognizer->add_option(GEOM_MODIFIER_3D); } + | SAT_OPTION { recognizer->add_option(SAT_OPTION); } + | FTZ_OPTION { recognizer->add_option(FTZ_OPTION); } + | NEG_OPTION { recognizer->add_option(NEG_OPTION); } + | APPROX_OPTION { recognizer->add_option(APPROX_OPTION); } + | FULL_OPTION { recognizer->add_option(FULL_OPTION); } + | EXIT_OPTION { recognizer->add_option(EXIT_OPTION); } + | ABS_OPTION { recognizer->add_option(ABS_OPTION); } | atomic_operation_spec ; - | TO_OPTION { add_option(TO_OPTION); } - | HALF_OPTION { add_option(HALF_OPTION); } - | EXTP_OPTION { add_option(EXTP_OPTION); } - | CA_OPTION { add_option(CA_OPTION); } - | CG_OPTION { add_option(CG_OPTION); } - | CS_OPTION { add_option(CS_OPTION); } - | LU_OPTION { add_option(LU_OPTION); } - | CV_OPTION { add_option(CV_OPTION); } - | WB_OPTION { add_option(WB_OPTION); } - | WT_OPTION { add_option(WT_OPTION); } - | NC_OPTION { add_option(NC_OPTION); } - | UP_OPTION { add_option(UP_OPTION); } - | DOWN_OPTION { add_option(DOWN_OPTION); } - | BFLY_OPTION { add_option(BFLY_OPTION); } - | IDX_OPTION { add_option(IDX_OPTION); } + | TO_OPTION { recognizer->add_option(TO_OPTION); } + | HALF_OPTION { recognizer->add_option(HALF_OPTION); } + | EXTP_OPTION { recognizer->add_option(EXTP_OPTION); } + | CA_OPTION { recognizer->add_option(CA_OPTION); } + | CG_OPTION { recognizer->add_option(CG_OPTION); } + | CS_OPTION { recognizer->add_option(CS_OPTION); } + | LU_OPTION { recognizer->add_option(LU_OPTION); } + | CV_OPTION { recognizer->add_option(CV_OPTION); } + | WB_OPTION { recognizer->add_option(WB_OPTION); } + | WT_OPTION { recognizer->add_option(WT_OPTION); } + | NC_OPTION { recognizer->add_option(NC_OPTION); } + | UP_OPTION { recognizer->add_option(UP_OPTION); } + | DOWN_OPTION { recognizer->add_option(DOWN_OPTION); } + | BFLY_OPTION { recognizer->add_option(BFLY_OPTION); } + | IDX_OPTION { recognizer->add_option(IDX_OPTION); } ; -atomic_operation_spec: ATOMIC_AND { add_option(ATOMIC_AND); } - | ATOMIC_POPC { add_option(ATOMIC_POPC); } - | ATOMIC_OR { add_option(ATOMIC_OR); } - | ATOMIC_XOR { add_option(ATOMIC_XOR); } - | ATOMIC_CAS { add_option(ATOMIC_CAS); } - | ATOMIC_EXCH { add_option(ATOMIC_EXCH); } - | ATOMIC_ADD { add_option(ATOMIC_ADD); } - | ATOMIC_INC { add_option(ATOMIC_INC); } - | ATOMIC_DEC { add_option(ATOMIC_DEC); } - | ATOMIC_MIN { add_option(ATOMIC_MIN); } - | ATOMIC_MAX { add_option(ATOMIC_MAX); } +atomic_operation_spec: ATOMIC_AND { recognizer->add_option(ATOMIC_AND); } + | ATOMIC_POPC { recognizer->add_option(ATOMIC_POPC); } + | ATOMIC_OR { recognizer->add_option(ATOMIC_OR); } + | ATOMIC_XOR { recognizer->add_option(ATOMIC_XOR); } + | ATOMIC_CAS { recognizer->add_option(ATOMIC_CAS); } + | ATOMIC_EXCH { recognizer->add_option(ATOMIC_EXCH); } + | ATOMIC_ADD { recognizer->add_option(ATOMIC_ADD); } + | ATOMIC_INC { recognizer->add_option(ATOMIC_INC); } + | ATOMIC_DEC { recognizer->add_option(ATOMIC_DEC); } + | ATOMIC_MIN { recognizer->add_option(ATOMIC_MIN); } + | ATOMIC_MAX { recognizer->add_option(ATOMIC_MAX); } ; rounding_mode: floating_point_rounding_mode | integer_rounding_mode; -floating_point_rounding_mode: RN_OPTION { add_option(RN_OPTION); } - | RZ_OPTION { add_option(RZ_OPTION); } - | RM_OPTION { add_option(RM_OPTION); } - | RP_OPTION { add_option(RP_OPTION); } +floating_point_rounding_mode: RN_OPTION { recognizer->add_option(RN_OPTION); } + | RZ_OPTION { recognizer->add_option(RZ_OPTION); } + | RM_OPTION { recognizer->add_option(RM_OPTION); } + | RP_OPTION { recognizer->add_option(RP_OPTION); } ; -integer_rounding_mode: RNI_OPTION { add_option(RNI_OPTION); } - | RZI_OPTION { add_option(RZI_OPTION); } - | RMI_OPTION { add_option(RMI_OPTION); } - | RPI_OPTION { add_option(RPI_OPTION); } +integer_rounding_mode: RNI_OPTION { recognizer->add_option(RNI_OPTION); } + | RZI_OPTION { recognizer->add_option(RZI_OPTION); } + | RMI_OPTION { recognizer->add_option(RMI_OPTION); } + | RPI_OPTION { recognizer->add_option(RPI_OPTION); } ; -compare_spec:EQ_OPTION { add_option(EQ_OPTION); } - | NE_OPTION { add_option(NE_OPTION); } - | LT_OPTION { add_option(LT_OPTION); } - | LE_OPTION { add_option(LE_OPTION); } - | GT_OPTION { add_option(GT_OPTION); } - | GE_OPTION { add_option(GE_OPTION); } - | LO_OPTION { add_option(LO_OPTION); } - | LS_OPTION { add_option(LS_OPTION); } - | HI_OPTION { add_option(HI_OPTION); } - | HS_OPTION { add_option(HS_OPTION); } - | EQU_OPTION { add_option(EQU_OPTION); } - | NEU_OPTION { add_option(NEU_OPTION); } - | LTU_OPTION { add_option(LTU_OPTION); } - | LEU_OPTION { add_option(LEU_OPTION); } - | GTU_OPTION { add_option(GTU_OPTION); } - | GEU_OPTION { add_option(GEU_OPTION); } - | NUM_OPTION { add_option(NUM_OPTION); } - | NAN_OPTION { add_option(NAN_OPTION); } +compare_spec:EQ_OPTION { recognizer->add_option(EQ_OPTION); } + | NE_OPTION { recognizer->add_option(NE_OPTION); } + | LT_OPTION { recognizer->add_option(LT_OPTION); } + | LE_OPTION { recognizer->add_option(LE_OPTION); } + | GT_OPTION { recognizer->add_option(GT_OPTION); } + | GE_OPTION { recognizer->add_option(GE_OPTION); } + | LO_OPTION { recognizer->add_option(LO_OPTION); } + | LS_OPTION { recognizer->add_option(LS_OPTION); } + | HI_OPTION { recognizer->add_option(HI_OPTION); } + | HS_OPTION { recognizer->add_option(HS_OPTION); } + | EQU_OPTION { recognizer->add_option(EQU_OPTION); } + | NEU_OPTION { recognizer->add_option(NEU_OPTION); } + | LTU_OPTION { recognizer->add_option(LTU_OPTION); } + | LEU_OPTION { recognizer->add_option(LEU_OPTION); } + | GTU_OPTION { recognizer->add_option(GTU_OPTION); } + | GEU_OPTION { recognizer->add_option(GEU_OPTION); } + | NUM_OPTION { recognizer->add_option(NUM_OPTION); } + | NAN_OPTION { recognizer->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); } +prmt_spec: PRMT_F4E_MODE { recognizer->add_option( PRMT_F4E_MODE); } + | PRMT_B4E_MODE { recognizer->add_option( PRMT_B4E_MODE); } + | PRMT_RC8_MODE { recognizer->add_option( PRMT_RC8_MODE); } + | PRMT_RC16_MODE{ recognizer->add_option( PRMT_RC16_MODE);} + | PRMT_ECL_MODE { recognizer->add_option( PRMT_ECL_MODE); } + | PRMT_ECR_MODE { recognizer->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);} +wmma_spec: WMMA_DIRECTIVE LAYOUT CONFIGURATION{recognizer->add_space_spec(global_space,0);recognizer->add_ptr_spec(global_space); recognizer->add_wmma_option($1);recognizer->add_wmma_option($2);recognizer->add_wmma_option($3);} + | WMMA_DIRECTIVE LAYOUT LAYOUT CONFIGURATION{recognizer->add_wmma_option($1);recognizer->add_wmma_option($2);recognizer->add_wmma_option($3);recognizer->add_wmma_option($4);} ; -vp_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);} +vp_spec: WMMA_DIRECTIVE LAYOUT CONFIGURATION{recognizer->add_space_spec(global_space,0);recognizer->add_ptr_spec(global_space);recognizer->add_wmma_option($1);recognizer->add_wmma_option($2);recognizer->add_wmma_option($3);} + | WMMA_DIRECTIVE LAYOUT LAYOUT CONFIGURATION{recognizer->add_wmma_option($1);recognizer->add_wmma_option($2);recognizer->add_wmma_option($3);recognizer->add_wmma_option($4);} ; @@ -550,80 +561,77 @@ vp_spec: WMMA_DIRECTIVE LAYOUT CONFIGURATION{add_space_spec(global_space,0);add_ operand_list: operand | operand COMMA operand_list; -operand: IDENTIFIER { add_scalar_operand( $1 ); } - | EXCLAMATION IDENTIFIER { add_neg_pred_operand( $2 ); } - | MINUS IDENTIFIER { add_scalar_operand( $2 ); change_operand_neg(); } +operand: IDENTIFIER { recognizer->add_scalar_operand( $1 ); } + | EXCLAMATION IDENTIFIER { recognizer->add_neg_pred_operand( $2 ); } + | MINUS IDENTIFIER { recognizer->add_scalar_operand( $2 ); recognizer->change_operand_neg(); } | memory_operand | literal_operand | builtin_operand | vector_operand - | MINUS vector_operand { change_operand_neg(); } + | MINUS vector_operand { recognizer->change_operand_neg(); } | tex_operand - | IDENTIFIER PLUS INT_OPERAND { add_address_operand($1,$3); } - | IDENTIFIER LO_OPTION { add_scalar_operand( $1 ); change_operand_lohi(1);} - | MINUS IDENTIFIER LO_OPTION { add_scalar_operand( $2 ); change_operand_lohi(1); change_operand_neg();} - | IDENTIFIER HI_OPTION { add_scalar_operand( $1 ); change_operand_lohi(2);} - | MINUS IDENTIFIER HI_OPTION { add_scalar_operand( $2 ); change_operand_lohi(2); change_operand_neg();} - | IDENTIFIER PIPE IDENTIFIER { add_2vector_operand($1,$3); change_double_operand_type(-1);} - | IDENTIFIER PIPE IDENTIFIER LO_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-1); change_operand_lohi(1);} - | IDENTIFIER PIPE IDENTIFIER HI_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-1); change_operand_lohi(2);} - | IDENTIFIER BACKSLASH IDENTIFIER { add_2vector_operand($1,$3); change_double_operand_type(-3);} - | IDENTIFIER BACKSLASH IDENTIFIER LO_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-3); change_operand_lohi(1);} - | IDENTIFIER BACKSLASH IDENTIFIER HI_OPTION { add_2vector_operand($1,$3); change_double_operand_type(-3); change_operand_lohi(2);} + | IDENTIFIER PLUS INT_OPERAND { recognizer->add_address_operand($1,$3); } + | IDENTIFIER LO_OPTION { recognizer->add_scalar_operand( $1 ); recognizer->change_operand_lohi(1);} + | MINUS IDENTIFIER LO_OPTION { recognizer->add_scalar_operand( $2 ); recognizer->change_operand_lohi(1); recognizer->change_operand_neg();} + | IDENTIFIER HI_OPTION { recognizer->add_scalar_operand( $1 ); recognizer->change_operand_lohi(2);} + | MINUS IDENTIFIER HI_OPTION { recognizer->add_scalar_operand( $2 ); recognizer->change_operand_lohi(2); recognizer->change_operand_neg();} + | IDENTIFIER PIPE IDENTIFIER { recognizer->add_2vector_operand($1,$3); recognizer->change_double_operand_type(-1);} + | IDENTIFIER PIPE IDENTIFIER LO_OPTION { recognizer->add_2vector_operand($1,$3); recognizer->change_double_operand_type(-1); recognizer->change_operand_lohi(1);} + | IDENTIFIER PIPE IDENTIFIER HI_OPTION { recognizer->add_2vector_operand($1,$3); recognizer->change_double_operand_type(-1); recognizer->change_operand_lohi(2);} + | IDENTIFIER BACKSLASH IDENTIFIER { recognizer->add_2vector_operand($1,$3); recognizer->change_double_operand_type(-3);} + | IDENTIFIER BACKSLASH IDENTIFIER LO_OPTION { recognizer->add_2vector_operand($1,$3); recognizer->change_double_operand_type(-3); recognizer->change_operand_lohi(1);} + | IDENTIFIER BACKSLASH IDENTIFIER HI_OPTION { recognizer->add_2vector_operand($1,$3); recognizer->change_double_operand_type(-3); recognizer->change_operand_lohi(2);} ; -vector_operand: LEFT_BRACE IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_2vector_operand($2,$4); } - | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_3vector_operand($2,$4,$6); } - | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_4vector_operand($2,$4,$6,$8); } - | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { add_8vector_operand($2,$4,$6,$8,$10,$12,$14,$16); } - | LEFT_BRACE IDENTIFIER RIGHT_BRACE { add_1vector_operand($2); } +vector_operand: LEFT_BRACE IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { recognizer->add_2vector_operand($2,$4); } + | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { recognizer->add_3vector_operand($2,$4,$6); } + | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { recognizer->add_4vector_operand($2,$4,$6,$8); } + | LEFT_BRACE IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { recognizer->add_8vector_operand($2,$4,$6,$8,$10,$12,$14,$16); } + | LEFT_BRACE IDENTIFIER RIGHT_BRACE { recognizer->add_1vector_operand($2); } ; -tex_operand: LEFT_SQUARE_BRACKET IDENTIFIER COMMA { add_scalar_operand($2); } +tex_operand: LEFT_SQUARE_BRACKET IDENTIFIER COMMA { recognizer->add_scalar_operand($2); } vector_operand RIGHT_SQUARE_BRACKET ; -builtin_operand: SPECIAL_REGISTER DIMENSION_MODIFIER { add_builtin_operand($1,$2); } - | SPECIAL_REGISTER { add_builtin_operand($1,-1); } +builtin_operand: SPECIAL_REGISTER DIMENSION_MODIFIER { recognizer->add_builtin_operand($1,$2); } + | SPECIAL_REGISTER { recognizer->add_builtin_operand($1,-1); } ; -memory_operand : LEFT_SQUARE_BRACKET address_expression RIGHT_SQUARE_BRACKET { add_memory_operand(); } - | IDENTIFIER LEFT_SQUARE_BRACKET address_expression RIGHT_SQUARE_BRACKET { add_memory_operand(); change_memory_addr_space($1); } - | IDENTIFIER LEFT_SQUARE_BRACKET literal_operand RIGHT_SQUARE_BRACKET { change_memory_addr_space($1); } - | IDENTIFIER LEFT_SQUARE_BRACKET twin_operand RIGHT_SQUARE_BRACKET { change_memory_addr_space($1); add_memory_operand();} - | MINUS memory_operand { change_operand_neg(); } +memory_operand : LEFT_SQUARE_BRACKET address_expression RIGHT_SQUARE_BRACKET { recognizer->add_memory_operand(); } + | IDENTIFIER LEFT_SQUARE_BRACKET address_expression RIGHT_SQUARE_BRACKET { recognizer->add_memory_operand(); recognizer->change_memory_addr_space($1); } + | IDENTIFIER LEFT_SQUARE_BRACKET literal_operand RIGHT_SQUARE_BRACKET { recognizer->change_memory_addr_space($1); } + | IDENTIFIER LEFT_SQUARE_BRACKET twin_operand RIGHT_SQUARE_BRACKET { recognizer->change_memory_addr_space($1); recognizer->add_memory_operand();} + | MINUS memory_operand { recognizer->change_operand_neg(); } ; -twin_operand : IDENTIFIER PLUS IDENTIFIER { add_double_operand($1,$3); change_double_operand_type(1); } - | IDENTIFIER PLUS IDENTIFIER LO_OPTION { add_double_operand($1,$3); change_double_operand_type(1); change_operand_lohi(1); } - | IDENTIFIER PLUS IDENTIFIER HI_OPTION { add_double_operand($1,$3); change_double_operand_type(1); change_operand_lohi(2); } - | IDENTIFIER PLUS EQUALS IDENTIFIER { add_double_operand($1,$4); change_double_operand_type(2); } - | IDENTIFIER PLUS EQUALS IDENTIFIER LO_OPTION { add_double_operand($1,$4); change_double_operand_type(2); change_operand_lohi(1); } - | IDENTIFIER PLUS EQUALS IDENTIFIER HI_OPTION { add_double_operand($1,$4); change_double_operand_type(2); change_operand_lohi(2); } - | IDENTIFIER PLUS EQUALS INT_OPERAND { add_address_operand($1,$4); change_double_operand_type(3); } +twin_operand : IDENTIFIER PLUS IDENTIFIER { recognizer->add_double_operand($1,$3); recognizer->change_double_operand_type(1); } + | IDENTIFIER PLUS IDENTIFIER LO_OPTION { recognizer->add_double_operand($1,$3); recognizer->change_double_operand_type(1); recognizer->change_operand_lohi(1); } + | IDENTIFIER PLUS IDENTIFIER HI_OPTION { recognizer->add_double_operand($1,$3); recognizer->change_double_operand_type(1); recognizer->change_operand_lohi(2); } + | IDENTIFIER PLUS EQUALS IDENTIFIER { recognizer->add_double_operand($1,$4); recognizer->change_double_operand_type(2); } + | IDENTIFIER PLUS EQUALS IDENTIFIER LO_OPTION { recognizer->add_double_operand($1,$4); recognizer->change_double_operand_type(2); recognizer->change_operand_lohi(1); } + | IDENTIFIER PLUS EQUALS IDENTIFIER HI_OPTION { recognizer->add_double_operand($1,$4); recognizer->change_double_operand_type(2); recognizer->change_operand_lohi(2); } + | IDENTIFIER PLUS EQUALS INT_OPERAND { recognizer->add_address_operand($1,$4); recognizer->change_double_operand_type(3); } ; -literal_operand : INT_OPERAND { add_literal_int($1); } - | FLOAT_OPERAND { add_literal_float($1); } - | DOUBLE_OPERAND { add_literal_double($1); } +literal_operand : INT_OPERAND { recognizer->add_literal_int($1); } + | FLOAT_OPERAND { recognizer->add_literal_float($1); } + | DOUBLE_OPERAND { recognizer->add_literal_double($1); } ; -address_expression: IDENTIFIER { add_address_operand($1,0); } - | IDENTIFIER LO_OPTION { add_address_operand($1,0); change_operand_lohi(1);} - | IDENTIFIER HI_OPTION { add_address_operand($1,0); change_operand_lohi(2); } - | IDENTIFIER PLUS INT_OPERAND { add_address_operand($1,$3); } - | INT_OPERAND { add_address_operand2($1); } +address_expression: IDENTIFIER { recognizer->add_address_operand($1,0); } + | IDENTIFIER LO_OPTION { recognizer->add_address_operand($1,0); recognizer->change_operand_lohi(1);} + | IDENTIFIER HI_OPTION { recognizer->add_address_operand($1,0); recognizer->change_operand_lohi(2); } + | IDENTIFIER PLUS INT_OPERAND { recognizer->add_address_operand($1,$3); } + | INT_OPERAND { recognizer->add_address_operand2($1); } ; %% -extern int ptx_lineno; -extern const char *g_filename; - -void syntax_not_implemented() +void syntax_not_implemented(yyscan_t yyscanner, ptx_recognizer* recognizer) { - printf("Parse error (%s:%u): this syntax is not (yet) implemented:\n",g_filename,ptx_lineno); - ptx_error(NULL); + printf("Parse error (%s): this syntax is not (yet) implemented:\n", recognizer->gpgpu_ctx->g_filename); + ptx_error(yyscanner, recognizer, NULL); abort(); } diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index e4e0c09..6978cc1 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -28,6 +28,7 @@ #include "ptx_parser.h" #include "ptx_ir.h" +typedef void * yyscan_t; #include "ptx.tab.h" #include "opcodes.h" #include <stdio.h> @@ -38,14 +39,21 @@ #include "assert.h" #include "cuda-sim.h" +#include "../../libcuda/gpgpu_context.h" #define STR_SIZE 1024 -unsigned symbol::sm_next_uid = 1; +const ptx_instruction* gpgpu_context::pc_to_instruction(unsigned pc) +{ + if( pc < s_g_pc_to_insn.size() ) + return s_g_pc_to_insn[pc]; + else + return NULL; +} unsigned symbol::get_uid() { - unsigned result = sm_next_uid++; + unsigned result = (gpgpu_ctx->symbol_sm_next_uid)++; return result; } @@ -82,8 +90,9 @@ symbol_table::symbol_table() assert(0); } -symbol_table::symbol_table( const char *scope_name, unsigned entry_point, symbol_table *parent ) +symbol_table::symbol_table( const char *scope_name, unsigned entry_point, symbol_table *parent, gpgpu_context* ctx ) { + gpgpu_ctx = ctx; m_scope_name = std::string(scope_name); m_reg_allocator=0; m_shared_next = 0; @@ -149,7 +158,7 @@ symbol *symbol_table::add_variable( const char *identifier, const type_info *typ std::string key(identifier); assert( m_symbols.find(key) == m_symbols.end() ); snprintf(buf,1024,"%s:%u",filename,line); - symbol *s = new symbol(identifier,type,buf,size); + symbol *s = new symbol(identifier,type,buf,size,gpgpu_ctx); m_symbols[ key ] = s; if ( type != NULL && type->get_key().is_global() ) { @@ -170,7 +179,7 @@ void symbol_table::add_function( function_info *func, const char *filename, unsi char buf[1024]; snprintf(buf,1024,"%s:%u",filename,linenumber); type_info *type = add_type( func ); - symbol *s = new symbol(func->get_name().c_str(),type,buf,0); + symbol *s = new symbol(func->get_name().c_str(),type,buf,0,gpgpu_ctx); s->set_function(func); m_symbols[ func->get_name() ] = s; } @@ -182,7 +191,7 @@ symbol_table* symbol_table::start_inst_group() { //previous added assert(m_inst_group_symtab.find(std::string(inst_group_name)) == m_inst_group_symtab.end()); - symbol_table *sym_table = new symbol_table(inst_group_name, 3/*inst group*/, this ); + symbol_table *sym_table = new symbol_table(inst_group_name, 3/*inst group*/, this, gpgpu_ctx ); sym_table->m_global_next = m_global_next; sym_table->m_shared_next = m_shared_next; @@ -220,7 +229,7 @@ bool symbol_table::add_function_decl( const char *name, int entry_point, functio *func_info = m_function_info_lookup[key]; prior_decl = true; } else { - *func_info = new function_info(entry_point); + *func_info = new function_info(entry_point, gpgpu_ctx); (*func_info)->set_name(name); (*func_info)->set_maxnt_id(0); m_function_info_lookup[key] = *func_info; @@ -231,7 +240,7 @@ bool symbol_table::add_function_decl( const char *name, int entry_point, functio *sym_table = m_function_symtab_lookup[key]; } else { assert( !prior_decl ); - *sym_table = new symbol_table( "", entry_point, this ); + *sym_table = new symbol_table( "", entry_point, this, gpgpu_ctx ); // Initial setup code to support a register represented as "_". // This register is used when an instruction operand is @@ -320,11 +329,9 @@ void symbol_table::dump() printf("\n"); } -unsigned operand_info::sm_next_uid=1; - unsigned operand_info::get_uid() { - unsigned result = sm_next_uid++; + unsigned result = (gpgpu_ctx->operand_info_sm_next_uid)++; return result; } @@ -1013,7 +1020,7 @@ void copy_buffer_to_frame(ptx_thread_info * thread, const arg_buffer_t &a) { if( a.is_reg() ) { ptx_reg_t value = a.get_reg(); - operand_info dst_reg = operand_info(a.get_dst()); + operand_info dst_reg = operand_info(a.get_dst(), thread->get_gpu()->gpgpu_ctx); thread->set_reg(dst_reg.get_symbol(),value); } else { const void *buffer = a.get_param_buffer(); @@ -1037,7 +1044,8 @@ void copy_buffer_list_into_frame(ptx_thread_info * thread, arg_buffer_list_t &ar static std::list<operand_info> check_operands( int opcode, const std::list<int> &scalar_type, - const std::list<operand_info> &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)) { @@ -1064,7 +1072,7 @@ static std::list<operand_info> check_operands( int opcode, if( (op.get_type() == double_op_t) && (inst_type == F32_TYPE) ) { ptx_reg_t v = op.get_literal_value(); float u = (float)v.f64; - operand_info n(u); + operand_info n(u, ctx); result.push_back(n); } else { result.push_back(op); @@ -1094,16 +1102,18 @@ ptx_instruction::ptx_instruction( int opcode, const char *file, unsigned line, const char *source, - const core_config *config ) : warp_inst_t(config) + const core_config *config, + gpgpu_context* ctx ) : warp_inst_t(config), m_return_var(ctx) { - m_uid = ++g_num_ptx_inst_uid; + gpgpu_ctx = ctx; + m_uid = ++(ctx->g_num_ptx_inst_uid); m_PC = 0; m_opcode = opcode; m_pred = pred; m_neg_pred = neg_pred; m_pred_mod = pred_mod; m_label = label; - const std::list<operand_info> checked_operands = check_operands(opcode,scalar_type,operands); + const std::list<operand_info> checked_operands = check_operands(opcode,scalar_type,operands, ctx); m_operands.insert(m_operands.begin(), checked_operands.begin(), checked_operands.end() ); m_return_var = return_var; m_options = options; @@ -1369,12 +1379,16 @@ std::string ptx_instruction::to_string() const m_source.c_str() ); return std::string( buf ); } +operand_info ptx_instruction::get_pred() const +{ + return operand_info( m_pred, gpgpu_ctx); +} -unsigned function_info::sm_next_uid = 1; -function_info::function_info(int entry_point ) +function_info::function_info(int entry_point, gpgpu_context* ctx ) { - m_uid = sm_next_uid++; + gpgpu_ctx = ctx; + m_uid = (gpgpu_ctx->function_info_sm_next_uid)++; m_entry_point = (entry_point==1)?true:false; m_extern = (entry_point==2)?true:false; num_reconvergence_pairs = 0; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 1af85de..f4c5c37 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -43,6 +43,8 @@ #include "memory.h" +class gpgpu_context; + class type_info_key { public: type_info_key() @@ -150,8 +152,9 @@ class operand_info; class symbol { public: - symbol( const char *name, const type_info *type, const char *location, unsigned size ) + symbol( const char *name, const type_info *type, const char *location, unsigned size, gpgpu_context* ctx ) { + gpgpu_ctx = ctx; m_uid = get_uid(); m_name = name; m_decl_location = location; @@ -271,6 +274,7 @@ public: unsigned uid() const { return m_uid; } private: + gpgpu_context* gpgpu_ctx; unsigned get_uid(); unsigned m_uid; const type_info *m_type; @@ -297,14 +301,12 @@ private: bool m_reg_num_valid; std::list<operand_info> m_initializer; - static unsigned sm_next_uid; - }; class symbol_table { public: symbol_table(); - symbol_table( const char *scope_name, unsigned entry_point, symbol_table *parent ); + symbol_table( const char *scope_name, unsigned entry_point, symbol_table *parent, gpgpu_context* ctx); void set_name( const char *name ); const ptx_version &get_ptx_version() const; unsigned get_sm_target() const; @@ -346,6 +348,9 @@ public: symbol_table* start_inst_group(); symbol_table* end_inst_group(); + // backward pointer + class gpgpu_context* gpgpu_ctx; + private: unsigned m_reg_allocator; unsigned m_shared_next; @@ -372,9 +377,9 @@ private: class operand_info { public: - operand_info() + operand_info(gpgpu_context* ctx) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -387,9 +392,9 @@ public: m_addr_offset = 0; m_value.m_symbolic=NULL; } - operand_info( const symbol *addr ) + operand_info( const symbol *addr, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -430,9 +435,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( const symbol *addr1, const symbol *addr2 ) + operand_info( const symbol *addr1, const symbol *addr2, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -457,9 +462,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( int builtin_id, int dim_mod ) + operand_info( int builtin_id, int dim_mod, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -476,9 +481,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( const symbol *addr, int offset ) + operand_info( const symbol *addr, int offset, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -495,9 +500,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( unsigned x ) + operand_info( unsigned x, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -514,9 +519,9 @@ public: m_is_return_var = false; m_immediate_address=true; } - operand_info( int x ) + operand_info( int x, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -533,9 +538,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( float x ) + operand_info( float x, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -552,9 +557,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( double x ) + operand_info( double x, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -571,9 +576,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( const symbol *s1, const symbol *s2, const symbol *s3, const symbol *s4 ) + operand_info( const symbol *s1, const symbol *s2, const symbol *s3, const symbol *s4, gpgpu_context* ctx ) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -598,9 +603,9 @@ public: m_is_return_var = false; m_immediate_address=false; } - operand_info( const symbol *s1, const symbol *s2, const symbol *s3, const symbol *s4 ,const symbol *s5,const symbol *s6,const symbol *s7, const symbol *s8) + operand_info( const symbol *s1, const symbol *s2, const symbol *s3, const symbol *s4 ,const symbol *s5,const symbol *s6,const symbol *s7, const symbol *s8, gpgpu_context* ctx) { - init(); + init(ctx); m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; @@ -626,8 +631,9 @@ public: m_immediate_address=false; } - void init() + void init(gpgpu_context* ctx) { + gpgpu_ctx = ctx; m_uid=(unsigned)-1; m_valid=false; m_vector=false; @@ -837,6 +843,7 @@ public: bool is_non_arch_reg() const { return m_is_non_arch_reg; } private: + gpgpu_context* gpgpu_ctx; unsigned m_uid; bool m_valid; bool m_vector; @@ -866,12 +873,10 @@ private: bool m_is_return_var; bool m_is_non_arch_reg; - static unsigned sm_next_uid; unsigned get_uid(); }; extern const char *g_opcode_string[]; -extern unsigned g_num_ptx_inst_uid; struct basic_block_t { basic_block_t( unsigned ID, ptx_instruction *begin, ptx_instruction *end, bool entry, bool ex) { @@ -931,7 +936,8 @@ public: const char *file, unsigned line, const char *source, - const core_config *config ); + const core_config *config, + gpgpu_context* ctx); void print_insn() const; virtual void print_insn( FILE *fp ) const; @@ -951,7 +957,7 @@ public: unsigned source_line() const { return m_source_line;} unsigned get_num_operands() const { return m_operands.size();} bool has_pred() const { return m_pred != NULL;} - operand_info get_pred() const { return operand_info( m_pred );} + operand_info get_pred() const; 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();} @@ -1186,7 +1192,8 @@ private: virtual void pre_decode(); friend class function_info; - static unsigned g_num_ptx_inst_uid; + // backward pointer + class gpgpu_context* gpgpu_ctx; }; class param_info { @@ -1228,7 +1235,7 @@ private: class function_info { public: - function_info(int entry_point ); + function_info(int entry_point, gpgpu_context* ctx ); const ptx_version &get_ptx_version() const { return m_symtab->get_ptx_version(); } unsigned get_sm_target() const { return m_symtab->get_sm_target(); } bool is_extern() const { return m_extern; } @@ -1365,13 +1372,6 @@ public: return m_symtab; } - static const ptx_instruction* pc_to_instruction(unsigned pc) - { - if( pc < s_g_pc_to_insn.size() ) - return s_g_pc_to_insn[pc]; - else - return NULL; - } unsigned local_mem_framesize() const { return m_local_mem_framesize; @@ -1398,6 +1398,8 @@ public: void set_maxnt_id(unsigned maxthreads) { maxnt_id = maxthreads;} unsigned get_maxnt_id() { return maxnt_id;} + // backward pointer + class gpgpu_context* gpgpu_ctx; private: unsigned maxnt_id; @@ -1427,9 +1429,6 @@ private: symbol_table *m_symtab; - static std::vector<ptx_instruction*> s_g_pc_to_insn; // a direct mapping from PC to instruction - static unsigned sm_next_uid; - //parameter size for device kernels int m_args_aligned_size; @@ -1438,14 +1437,14 @@ private: class arg_buffer_t { public: - arg_buffer_t() + arg_buffer_t(gpgpu_context* ctx) : m_src_op(ctx) { m_is_reg=false; m_is_param=false; m_param_value=NULL; m_reg_value=ptx_reg_t(); } - arg_buffer_t( const arg_buffer_t &another ) + arg_buffer_t( const arg_buffer_t &another, gpgpu_context* ctx ) : m_src_op(ctx) { make_copy(another); } @@ -1575,11 +1574,8 @@ struct textureInfo { extern std::map<std::string,symbol_table*> g_sym_name_to_symbol_table; -extern bool g_keep_intermediate_files; - void gpgpu_ptx_assemble( std::string kname, void *kinfo ); #include "../option_parser.h" -void ptx_reg_options(option_parser_t opp); unsigned ptx_kernel_shmem_size( void *kernel_impl ); unsigned ptx_kernel_nregs( void *kernel_impl ); diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 8c6f361..dca3cec 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -33,44 +33,40 @@ #include <dirent.h> #include <fstream> #include <sstream> - -/// globals - -memory_space *g_global_mem; -memory_space *g_tex_mem; -memory_space *g_surf_mem; -memory_space *g_param_mem; -bool g_override_embedded_ptx = false; +#include "../../libcuda/gpgpu_context.h" /// extern prototypes -extern int ptx_parse(); -extern int ptx__scan_string(const char*); +extern int ptx_error( yyscan_t yyscanner, const char *s ); +extern int ptx_lex_init(yyscan_t* scanner); +extern void ptx_set_in(FILE * _in_str ,yyscan_t yyscanner ); +extern int ptx_parse(yyscan_t scanner, ptx_recognizer* recognizer); +extern int ptx_lex_destroy(yyscan_t scanner); +extern int ptx__scan_string(const char*, yyscan_t scanner); extern std::map<unsigned,const char*> get_duplicate(); -const char *g_ptxinfo_filename; -extern int ptxinfo_parse(); -extern int ptxinfo_debug; -extern FILE *ptxinfo_in; +typedef void * yyscan_t; +extern int ptxinfo_lex_init(yyscan_t* scanner); +extern void ptxinfo_set_in (FILE * _in_str ,yyscan_t yyscanner ); +extern int ptxinfo_parse(yyscan_t scanner, ptxinfo_data* ptxinfo); +extern int ptxinfo_lex_destroy(yyscan_t scanner); static bool g_save_embedded_ptx; static int g_occupancy_sm_number; -bool g_keep_intermediate_files; -bool m_ptx_save_converted_ptxplus; -bool keep_intermediate_files() {return g_keep_intermediate_files;} +bool ptxinfo_data::keep_intermediate_files() {return g_keep_intermediate_files;} -void ptx_reg_options(option_parser_t opp) +void gpgpu_context::ptx_reg_options(option_parser_t opp) { option_parser_register(opp, "-save_embedded_ptx", OPT_BOOL, &g_save_embedded_ptx, "saves ptx files embedded in binary as <n>.ptx", "0"); - option_parser_register(opp, "-keep", OPT_BOOL, &g_keep_intermediate_files, + option_parser_register(opp, "-keep", OPT_BOOL, &(ptxinfo->g_keep_intermediate_files), "keep intermediate files created by GPGPU-Sim when interfacing with external programs", "0"); option_parser_register(opp, "-gpgpu_ptx_save_converted_ptxplus", OPT_BOOL, - &m_ptx_save_converted_ptxplus, + &(ptxinfo->m_ptx_save_converted_ptxplus), "Saved converted ptxplus to a file", "0"); option_parser_register(opp, "-gpgpu_occupancy_sm_number", OPT_INT32, &g_occupancy_sm_number, @@ -79,7 +75,7 @@ void ptx_reg_options(option_parser_t opp) "0"); } -void print_ptx_file( const char *p, unsigned source_num, const char *filename ) +void gpgpu_context::print_ptx_file( const char *p, unsigned source_num, const char *filename ) { printf("\nGPGPU-Sim PTX: file _%u.ptx contents:\n\n", source_num ); char *s = strdup(p); @@ -90,7 +86,7 @@ void print_ptx_file( const char *p, unsigned source_num, const char *filename ) while ( (*u != '\n') && (*u != '\0') ) u++; unsigned last = (*u == '\0'); *u = '\0'; - const ptx_instruction *pI = ptx_instruction_lookup(filename,n); + const ptx_instruction *pI = ptx_parser->ptx_instruction_lookup(filename,n); char pc[64]; if( pI && pI->get_PC() ) snprintf(pc,64,"%4u", pI->get_PC() ); @@ -105,7 +101,7 @@ void print_ptx_file( const char *p, unsigned source_num, const char *filename ) fflush(stdout); } -char* gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptxfilename, const std::string elffilename, const std::string sassfilename) +char* ptxinfo_data::gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptxfilename, const std::string elffilename, const std::string sassfilename) { printf("GPGPU-Sim PTX: converting EMBEDDED .ptx file to ptxplus \n"); @@ -158,7 +154,7 @@ char* gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptxfilenam } -symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ) +symbol_table *gpgpu_context::gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ) { char buf[1024]; snprintf(buf,1024,"_%u.ptx", source_num ); @@ -168,8 +164,9 @@ symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source fclose(fp); } symbol_table *symtab=init_parser(buf); - ptx__scan_string(p); - int errors = ptx_parse (); + ptx_lex_init(&(ptx_parser->scanner)); + ptx__scan_string(p, ptx_parser->scanner); + int errors = ptx_parse (ptx_parser->scanner, ptx_parser); if ( errors ) { char fname[1024]; snprintf(fname,1024,"_ptx_errors_XXXXXX"); @@ -182,6 +179,7 @@ symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source abort(); exit(40); } + ptx_lex_destroy(ptx_parser->scanner); if ( g_debug_execution >= 100 ) print_ptx_file(p,source_num,buf); @@ -190,7 +188,7 @@ symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source return symtab; } -symbol_table *gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ) +symbol_table *gpgpu_context::gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ) { symbol_table *symtab=init_parser(filename); printf("GPGPU-Sim PTX: finished parsing EMBEDDED .ptx file %s\n",filename); @@ -327,13 +325,12 @@ char* get_app_binary_name(){ return self_exe_path; } -void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_version) +void gpgpu_context::gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_version) { std::string ptxas_filename(std::string(filename) + "as"); char buff[1024], extra_flags[1024]; extra_flags[0]=0; - extern bool g_cdp_enabled; - if(!g_cdp_enabled) + if(!device_runtime->g_cdp_enabled) snprintf(extra_flags,1024,"--gpu-name=sm_%u",sm_version); else snprintf(extra_flags,1024,"--compile-only --gpu-name=sm_%u",sm_version); @@ -346,13 +343,17 @@ void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_versio exit(1); } - g_ptxinfo_filename = strdup(ptxas_filename.c_str()); - ptxinfo_in = fopen(g_ptxinfo_filename,"r"); - ptxinfo_parse(); + FILE *ptxinfo_in; + ptxinfo->g_ptxinfo_filename = strdup(ptxas_filename.c_str()); + ptxinfo_in = fopen(ptxinfo->g_ptxinfo_filename,"r"); + ptxinfo_lex_init(&(ptxinfo->scanner)); + ptxinfo_set_in(ptxinfo_in, ptxinfo->scanner); + ptxinfo_parse(ptxinfo->scanner, ptxinfo); + ptxinfo_lex_destroy(ptxinfo->scanner); fclose(ptxinfo_in); } -void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version ) +void gpgpu_context::gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version, int no_of_ptx ) { //do ptxas for individual files instead of one big embedded ptx. This prevents the duplicate defs and declarations. char ptx_file[1000]; @@ -396,8 +397,7 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num "A register size/SM mismatch may result in occupancy differences." ); exit(1); } - extern bool g_cdp_enabled; - if(!g_cdp_enabled) + if(!device_runtime->g_cdp_enabled) snprintf(extra_flags,1024,"--gpu-name=sm_%u", g_occupancy_sm_number); else snprintf(extra_flags,1024,"--compile-only --gpu-name=sm_%u",g_occupancy_sm_number); @@ -410,9 +410,14 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num if( result != 0 ) { // 65280 = duplicate errors if (result == 65280) { + FILE *ptxinfo_in; ptxinfo_in = fopen(tempfile_ptxinfo,"r"); - g_ptxinfo_filename = tempfile_ptxinfo; - ptxinfo_parse(); + ptxinfo->g_ptxinfo_filename = tempfile_ptxinfo; + ptxinfo_lex_init(&(ptxinfo->scanner)); + ptxinfo_set_in(ptxinfo_in, ptxinfo->scanner); + ptxinfo_parse(ptxinfo->scanner, ptxinfo); + ptxinfo_lex_destroy(ptxinfo->scanner); + fclose(ptxinfo_in); fix_duplicate_errors(fname2); snprintf(commandline,1024,"$CUDA_INSTALL_PATH/bin/ptxas %s -v %s --output-file /dev/null 2> %s", @@ -460,8 +465,7 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num #if CUDART_VERSION >= 3000 if (sm_version == 0) sm_version = 20; - extern bool g_cdp_enabled; - if(!g_cdp_enabled) + if(!device_runtime->g_cdp_enabled) snprintf(extra_flags,1024,"--gpu-name=sm_%u",sm_version); else snprintf(extra_flags,1024,"--compile-only --gpu-name=sm_%u",sm_version); @@ -492,12 +496,17 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num } if(no_of_ptx>0) - g_ptxinfo_filename = final_tempfile_ptxinfo; + ptxinfo->g_ptxinfo_filename = final_tempfile_ptxinfo; else - g_ptxinfo_filename = tempfile_ptxinfo; - ptxinfo_in = fopen(g_ptxinfo_filename,"r"); + ptxinfo->g_ptxinfo_filename = tempfile_ptxinfo; + FILE *ptxinfo_in; + ptxinfo_in = fopen(ptxinfo->g_ptxinfo_filename,"r"); - ptxinfo_parse(); + ptxinfo_lex_init(&(ptxinfo->scanner)); + ptxinfo_set_in(ptxinfo_in, ptxinfo->scanner); + ptxinfo_parse(ptxinfo->scanner, ptxinfo); + ptxinfo_lex_destroy(ptxinfo->scanner); + fclose(ptxinfo_in); snprintf(commandline,1024,"rm -f *info"); if( system(commandline) != 0 ) { @@ -515,4 +524,4 @@ void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num exit(1); } } -}
\ No newline at end of file +} diff --git a/src/cuda-sim/ptx_loader.h b/src/cuda-sim/ptx_loader.h index e5df6a9..d8f1cbc 100644 --- a/src/cuda-sim/ptx_loader.h +++ b/src/cuda-sim/ptx_loader.h @@ -29,14 +29,24 @@ #define PTX_LOADER_H_INCLUDED #include <string> -extern bool g_override_embedded_ptx; -extern int no_of_ptx; //counter to track number of ptx files to be extracted in an application. - -class symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ); -class symbol_table *gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ); -void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version=20 ); -void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_version ); -char* gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptx_str, const std::string sass_str, const std::string elf_str); -bool keep_intermediate_files(); +#define PTXINFO_LINEBUF_SIZE 1024 +class gpgpu_context; +typedef void * yyscan_t; +class ptxinfo_data{ + public: + ptxinfo_data(gpgpu_context* ctx) { + gpgpu_ctx = ctx; + } + yyscan_t scanner; + char linebuf[PTXINFO_LINEBUF_SIZE]; + unsigned col; + const char *g_ptxinfo_filename; + class gpgpu_context* gpgpu_ctx; + bool g_keep_intermediate_files; + bool m_ptx_save_converted_ptxplus; + void ptxinfo_addinfo(); + bool keep_intermediate_files(); + char* gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptx_str, const std::string sass_str, const std::string elf_str); +}; #endif diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index 25758dd..81b70af 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -27,79 +27,46 @@ #include "ptx_parser.h" #include "ptx_ir.h" +#include "../../libcuda/gpgpu_context.h" + +typedef void * yyscan_t; #include "ptx.tab.h" #include <stdarg.h> -extern int ptx_error( const char *s ); -extern int ptx_lineno; -extern int ptx_parse(); -extern FILE *ptx_in; +extern int ptx_get_lineno (yyscan_t yyscanner ); +extern YYSTYPE* ptx_get_lval (yyscan_t yyscanner ); +extern int ptx_error( yyscan_t yyscanner, const char *s ); +extern int ptx_lex_init(yyscan_t* scanner); +extern void ptx_set_in(FILE * _in_str ,yyscan_t yyscanner ); +extern FILE *ptx_get_in (yyscan_t yyscanner ); +extern int ptx_parse(yyscan_t scanner, ptx_recognizer* recognizer); +extern int ptx_lex_destroy(yyscan_t scanner); -static const struct core_config *g_shader_core_config; -void set_ptx_warp_size(const struct core_config * warp_size) +void ptx_recognizer::set_ptx_warp_size(const struct core_config * warp_size) { g_shader_core_config=warp_size; } -static bool g_debug_ir_generation=false; -const char *g_filename; -unsigned g_max_regs_per_thread = 0; - -// the program intermediate representation... -static symbol_table *g_global_allfiles_symbol_table = NULL; -static symbol_table *g_global_symbol_table = NULL; -std::map<std::string,symbol_table*> g_sym_name_to_symbol_table; -static symbol_table *g_current_symbol_table = NULL; -static std::list<ptx_instruction*> g_instructions; -static symbol *g_last_symbol = NULL; - -int g_error_detected = 0; - -// type specifier stuff: -memory_space_t g_space_spec = undefined_space; -memory_space_t g_ptr_spec = undefined_space; -int g_scalar_type_spec = -1; -int g_vector_spec = -1; -int g_alignment_spec = -1; -int g_size = -1; -int g_extern_spec = 0; - -// variable declaration stuff: -type_info *g_var_type = NULL; - -// instruction definition stuff: -const symbol *g_pred; -int g_neg_pred; -int g_pred_mod; -symbol *g_label; -int g_opcode = -1; -std::list<operand_info> g_operands; -std::list<int> g_options; -std::list<int> g_wmma_options; -std::list<int> g_scalar_type; #define PTX_PARSE_DPRINTF(...) \ if( g_debug_ir_generation ) { \ - printf(" %s:%u => ",g_filename,ptx_lineno); \ + printf(" %s:%u => ",gpgpu_ctx->g_filename,ptx_get_lineno(scanner)); \ printf(" (%s:%u) ", __FILE__, __LINE__); \ printf(__VA_ARGS__); \ printf("\n"); \ fflush(stdout); \ } -static unsigned g_entry_func_param_index=0; -static function_info *g_func_info = NULL; static std::map<unsigned,std::string> g_ptx_token_decode; -static operand_info g_return_var; const char *decode_token( int type ) { return g_ptx_token_decode[type].c_str(); } -void read_parser_environment_variables() +void ptx_recognizer::read_parser_environment_variables() { - g_filename = getenv("PTX_SIM_KERNELFILE"); + gpgpu_ctx->g_filename = getenv("PTX_SIM_KERNELFILE"); char *dbg_level = getenv("PTX_SIM_DEBUG"); if ( dbg_level && strlen(dbg_level) ) { int debug_execution=0; @@ -109,7 +76,7 @@ void read_parser_environment_variables() } } -void init_directive_state() +void ptx_recognizer::init_directive_state() { PTX_PARSE_DPRINTF("init_directive_state"); g_space_spec=undefined_space; @@ -125,7 +92,7 @@ void init_directive_state() g_last_symbol = NULL; } -void init_instruction_state() +void ptx_recognizer::init_instruction_state() { PTX_PARSE_DPRINTF("init_instruction_state"); g_pred = NULL; @@ -135,21 +102,20 @@ void init_instruction_state() g_opcode = -1; g_options.clear(); g_wmma_options.clear(); - g_return_var = operand_info(); + g_return_var = operand_info(gpgpu_ctx); init_directive_state(); } -symbol_table *init_parser( const char *ptx_filename ) +symbol_table * gpgpu_context::init_parser( const char *ptx_filename ) { g_filename = strdup(ptx_filename); if (g_global_allfiles_symbol_table == NULL) { - g_global_allfiles_symbol_table = new symbol_table("global_allfiles", 0, NULL); - g_global_symbol_table = g_current_symbol_table = g_global_allfiles_symbol_table; + g_global_allfiles_symbol_table = new symbol_table("global_allfiles", 0, NULL, this); + ptx_parser->g_global_symbol_table = ptx_parser->g_current_symbol_table = g_global_allfiles_symbol_table; } /*else { g_global_symbol_table = g_current_symbol_table = new symbol_table("global",0,g_global_allfiles_symbol_table); }*/ - ptx_lineno = 1; #define DEF(X,Y) g_ptx_token_decode[X] = Y; #include "ptx_parser_decode.def" @@ -169,18 +135,22 @@ symbol_table *init_parser( const char *ptx_filename ) g_ptx_token_decode[generic_space] = "generic_space"; g_ptx_token_decode[instruction_space] = "instruction_space"; - init_directive_state(); - init_instruction_state(); + ptx_lex_init(&(ptx_parser->scanner)); + ptx_parser->init_directive_state(); + ptx_parser->init_instruction_state(); + FILE *ptx_in; ptx_in = fopen(ptx_filename, "r"); - ptx_parse(); + ptx_set_in(ptx_in, ptx_parser->scanner); + ptx_parse(ptx_parser->scanner, ptx_parser); + ptx_in = ptx_get_in(ptx_parser->scanner); + ptx_lex_destroy(ptx_parser->scanner); fclose(ptx_in); - return g_global_symbol_table; + return ptx_parser->g_global_symbol_table; } -static int g_entry_point; -void start_function( int entry_point ) +void ptx_recognizer::start_function( int entry_point ) { PTX_PARSE_DPRINTF("start_function"); init_directive_state(); @@ -190,11 +160,7 @@ void start_function( int entry_point ) g_entry_func_param_index=0; } -char *g_add_identifier_cached__identifier = NULL; -int g_add_identifier_cached__array_dim; -int g_add_identifier_cached__array_ident; - -void add_function_name( const char *name ) +void ptx_recognizer::add_function_name( const char *name ) { PTX_PARSE_DPRINTF("add_function_name %s %s", name, ((g_entry_point==1)?"(entrypoint)":((g_entry_point==2)?"(extern)":""))); bool prior_decl = g_global_symbol_table->add_function_decl( name, g_entry_point, &g_func_info, &g_current_symbol_table ); @@ -210,21 +176,21 @@ void add_function_name( const char *name ) if( prior_decl ) { g_func_info->remove_args(); } - g_global_symbol_table->add_function( g_func_info, g_filename, ptx_lineno ); + g_global_symbol_table->add_function( g_func_info, gpgpu_ctx->g_filename, ptx_get_lineno(scanner) ); } //Jin: handle instruction group for cdp -void start_inst_group() { +void ptx_recognizer::start_inst_group() { PTX_PARSE_DPRINTF("start_instruction_group"); g_current_symbol_table = g_current_symbol_table->start_inst_group(); } -void end_inst_group() { +void ptx_recognizer::end_inst_group() { PTX_PARSE_DPRINTF("end_instruction_group"); g_current_symbol_table = g_current_symbol_table->end_inst_group(); } -void add_directive() +void ptx_recognizer::add_directive() { PTX_PARSE_DPRINTF("add_directive"); init_directive_state(); @@ -232,7 +198,7 @@ void add_directive() #define mymax(a,b) ((a)>(b)?(a):(b)) -void end_function() +void ptx_recognizer::end_function() { PTX_PARSE_DPRINTF("end_function"); @@ -250,7 +216,7 @@ void end_function() #define parse_error(msg, ...) parse_error_impl(__FILE__,__LINE__, msg, ##__VA_ARGS__) #define parse_assert(cond,msg, ...) parse_assert_impl((cond),__FILE__,__LINE__, msg, ##__VA_ARGS__) -void parse_error_impl( const char *file, unsigned line, const char *msg, ... ) +void ptx_recognizer::parse_error_impl( const char *file, unsigned line, const char *msg, ... ) { va_list ap; char buf[1024]; @@ -259,13 +225,13 @@ void parse_error_impl( const char *file, unsigned line, const char *msg, ... ) va_end(ap); g_error_detected = 1; - printf("%s:%u: Parse error: %s (%s:%u)\n\n", g_filename, ptx_lineno, buf, file, line); - ptx_error(NULL); + printf("%s:%u: Parse error: %s (%s:%u)\n\n", gpgpu_ctx->g_filename, ptx_get_lineno(scanner), buf, file, line); + ptx_error(scanner, NULL); abort(); exit(1); } -void parse_assert_impl( int test_value, const char *file, unsigned line, const char *msg, ... ) +void ptx_recognizer::parse_assert_impl( int test_value, const char *file, unsigned line, const char *msg, ... ) { va_list ap; char buf[1024]; @@ -277,19 +243,17 @@ void parse_assert_impl( int test_value, const char *file, unsigned line, const c parse_error_impl(file,line, msg); } -extern char linebuf[4096]; -void set_return() +void ptx_recognizer::set_return() { parse_assert( (g_opcode == CALL_OP || g_opcode == CALLP_OP), "only call can have return value"); g_operands.front().set_return(); g_return_var = g_operands.front(); } -std::map<std::string,std::map<unsigned,const ptx_instruction*> > g_inst_lookup; -const ptx_instruction *ptx_instruction_lookup( const char *filename, unsigned linenumber ) +const ptx_instruction *ptx_recognizer::ptx_instruction_lookup( const char *filename, unsigned linenumber ) { std::map<std::string,std::map<unsigned,const ptx_instruction*> >::iterator f=g_inst_lookup.find(filename); if( f == g_inst_lookup.end() ) @@ -300,7 +264,7 @@ const ptx_instruction *ptx_instruction_lookup( const char *filename, unsigned li return l->second; } -void add_instruction() +void ptx_recognizer::add_instruction() { PTX_PARSE_DPRINTF("add_instruction: %s", ((g_opcode>0)?g_opcode_string[g_opcode]:"<label>") ); assert( g_shader_core_config != 0 ); @@ -315,16 +279,17 @@ void add_instruction() g_wmma_options, g_scalar_type, g_space_spec, - g_filename, - ptx_lineno, + gpgpu_ctx->g_filename, + ptx_get_lineno(scanner), linebuf, - g_shader_core_config ); + g_shader_core_config, + gpgpu_ctx ); g_instructions.push_back(i); - g_inst_lookup[g_filename][ptx_lineno] = i; + g_inst_lookup[gpgpu_ctx->g_filename][ptx_get_lineno(scanner)] = i; init_instruction_state(); } -void add_variables() +void ptx_recognizer::add_variables() { PTX_PARSE_DPRINTF("add_variables"); if ( !g_operands.empty() ) { @@ -334,7 +299,7 @@ void add_variables() init_directive_state(); } -void set_variable_type() +void ptx_recognizer::set_variable_type() { PTX_PARSE_DPRINTF("set_variable_type space_spec=%s scalar_type_spec=%s", g_ptx_token_decode[g_space_spec.get_type()].c_str(), @@ -348,19 +313,12 @@ void set_variable_type() g_extern_spec ); } -bool check_for_duplicates( const char *identifier ) +bool ptx_recognizer::check_for_duplicates( const char *identifier ) { const symbol *s = g_current_symbol_table->lookup(identifier); return ( s != NULL ); } -extern std::set<std::string> g_globals; -extern std::set<std::string> g_constants; - -int g_func_decl = 0; -int g_ident_add_uid = 0; -unsigned g_const_alloc = 1; - // Returns padding that needs to be inserted ahead of address to make it aligned to min(size, maxalign) /* * @param address the address in bytes @@ -378,7 +336,7 @@ int pad_address (new_addr_type address, unsigned size, unsigned maxalign) { return alignto ? ((alignto - (address % alignto)) % alignto) : 0; } -void add_identifier( const char *identifier, int array_dim, unsigned array_ident ) +void ptx_recognizer::add_identifier( const char *identifier, int array_dim, unsigned array_ident ) { if(array_ident==ARRAY_IDENTIFIER){ g_size *= array_dim; @@ -426,7 +384,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident default: break; } - g_last_symbol = g_current_symbol_table->add_variable(identifier,type,num_bits/8,g_filename,ptx_lineno); + g_last_symbol = g_current_symbol_table->add_variable(identifier,type,num_bits/8,gpgpu_ctx->g_filename,ptx_get_lineno(scanner)); switch ( ti.get_memory_space().get_type() ) { case reg_space: { regnum = g_current_symbol_table->next_reg_num(); @@ -489,7 +447,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident g_current_symbol_table->alloc_global( num_bits/8 + addr_pad ); } if( g_current_symbol_table == g_global_symbol_table ) { - g_constants.insert( identifier ); + gpgpu_ctx->func_sim->g_constants.insert( identifier ); } assert( g_current_symbol_table != NULL ); g_sym_name_to_symbol_table[ identifier ] = g_current_symbol_table; @@ -507,7 +465,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident fflush(stdout); g_last_symbol->set_address( addr+addr_pad ); g_current_symbol_table->alloc_global( num_bits/8 + addr_pad ); - g_globals.insert( identifier ); + gpgpu_ctx->func_sim->g_globals.insert( identifier ); assert( g_current_symbol_table != NULL ); g_sym_name_to_symbol_table[ identifier ] = g_current_symbol_table; break; @@ -569,7 +527,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident } } -void add_constptr(const char* identifier1, const char* identifier2, int offset) +void ptx_recognizer::add_constptr(const char* identifier1, const char* identifier2, int offset) { symbol *s1 = g_current_symbol_table->lookup(identifier1); const symbol *s2 = g_current_symbol_table->lookup(identifier2); @@ -584,7 +542,7 @@ void add_constptr(const char* identifier1, const char* identifier2, int offset) s1->set_address( addr + offset ); } -void add_function_arg() +void ptx_recognizer::add_function_arg() { assert(g_size>0); if( g_func_info ) { @@ -597,20 +555,20 @@ void add_function_arg() } -void add_extern_spec() +void ptx_recognizer::add_extern_spec() { PTX_PARSE_DPRINTF("add_extern_spec"); g_extern_spec = 1; } -void add_alignment_spec( int spec ) +void ptx_recognizer::add_alignment_spec( int spec ) { PTX_PARSE_DPRINTF("add_alignment_spec"); parse_assert( g_alignment_spec == -1, "multiple .align specifiers per variable declaration not allowed." ); g_alignment_spec = spec; } -void add_ptr_spec( enum _memory_space_t spec ) +void ptx_recognizer::add_ptr_spec( enum _memory_space_t spec ) { PTX_PARSE_DPRINTF("add_ptr_spec \"%s\"", g_ptx_token_decode[spec].c_str() ); parse_assert( g_ptr_spec == undefined_space, "multiple ptr space specifiers not allowed." ); @@ -618,7 +576,7 @@ void add_ptr_spec( enum _memory_space_t spec ) g_ptr_spec = spec; } -void add_space_spec( enum _memory_space_t spec, int value ) +void ptx_recognizer::add_space_spec( enum _memory_space_t spec, int value ) { PTX_PARSE_DPRINTF("add_space_spec \"%s\"", g_ptx_token_decode[spec].c_str() ); parse_assert( g_space_spec == undefined_space, "multiple space specifiers not allowed." ); @@ -637,14 +595,14 @@ void add_space_spec( enum _memory_space_t spec, int value ) } } -void add_vector_spec(int spec ) +void ptx_recognizer::add_vector_spec(int spec ) { PTX_PARSE_DPRINTF("add_vector_spec"); parse_assert( g_vector_spec == -1, "multiple vector specifiers not allowed." ); g_vector_spec = spec; } -void add_scalar_type_spec( int type_spec ) +void ptx_recognizer::add_scalar_type_spec( int type_spec ) { //save size of parameter switch ( type_spec ) { @@ -682,23 +640,23 @@ void add_scalar_type_spec( int type_spec ) g_scalar_type_spec = type_spec; } -void add_label( const char *identifier ) +void ptx_recognizer::add_label( const char *identifier ) { PTX_PARSE_DPRINTF("add_label"); symbol *s = g_current_symbol_table->lookup(identifier); if ( s != NULL ) { g_label = s; } else { - g_label = g_current_symbol_table->add_variable(identifier,NULL,0,g_filename,ptx_lineno); + g_label = g_current_symbol_table->add_variable(identifier,NULL,0,gpgpu_ctx->g_filename,ptx_get_lineno(scanner)); } } -void add_opcode( int opcode ) +void ptx_recognizer::add_opcode( int opcode ) { g_opcode = opcode; } -void add_pred( const char *identifier, int neg, int predModifier ) +void ptx_recognizer::add_pred( const char *identifier, int neg, int predModifier ) { PTX_PARSE_DPRINTF("add_pred"); const symbol *s = g_current_symbol_table->lookup(identifier); @@ -711,17 +669,17 @@ void add_pred( const char *identifier, int neg, int predModifier ) g_pred_mod = predModifier; } -void add_option( int option ) +void ptx_recognizer::add_option( int option ) { PTX_PARSE_DPRINTF("add_option"); g_options.push_back( option ); } -void add_wmma_option( int option ) +void ptx_recognizer::add_wmma_option( int option ) { PTX_PARSE_DPRINTF("add_option"); g_wmma_options.push_back( option ); } -void add_double_operand( const char *d1, const char *d2 ) +void ptx_recognizer::add_double_operand( const char *d1, const char *d2 ) { //operands that access two variables. //eg. s[$ofs1+$r0], g[$ofs1+=$r0] @@ -731,38 +689,38 @@ void add_double_operand( const char *d1, const char *d2 ) const symbol *s1 = g_current_symbol_table->lookup(d1); const symbol *s2 = g_current_symbol_table->lookup(d2); parse_assert( s1 != NULL && s2 != NULL, "component(s) missing declarations."); - g_operands.push_back( operand_info(s1,s2) ); + g_operands.push_back( operand_info(s1,s2,gpgpu_ctx) ); } -void add_1vector_operand( const char *d1 ) +void ptx_recognizer::add_1vector_operand( const char *d1 ) { // handles the single element vector operand ({%v1}) found in tex.1d instructions PTX_PARSE_DPRINTF("add_1vector_operand"); const symbol *s1 = g_current_symbol_table->lookup(d1); parse_assert( s1 != NULL, "component(s) missing declarations."); - g_operands.push_back( operand_info(s1,NULL,NULL,NULL) ); + g_operands.push_back( operand_info(s1,NULL,NULL,NULL,gpgpu_ctx) ); } -void add_2vector_operand( const char *d1, const char *d2 ) +void ptx_recognizer::add_2vector_operand( const char *d1, const char *d2 ) { PTX_PARSE_DPRINTF("add_2vector_operand"); const symbol *s1 = g_current_symbol_table->lookup(d1); const symbol *s2 = g_current_symbol_table->lookup(d2); parse_assert( s1 != NULL && s2 != NULL, "v2 component(s) missing declarations."); - g_operands.push_back( operand_info(s1,s2,NULL,NULL) ); + g_operands.push_back( operand_info(s1,s2,NULL,NULL,gpgpu_ctx) ); } -void add_3vector_operand( const char *d1, const char *d2, const char *d3 ) +void ptx_recognizer::add_3vector_operand( const char *d1, const char *d2, const char *d3 ) { PTX_PARSE_DPRINTF("add_3vector_operand"); const symbol *s1 = g_current_symbol_table->lookup(d1); const symbol *s2 = g_current_symbol_table->lookup(d2); const symbol *s3 = g_current_symbol_table->lookup(d3); parse_assert( s1 != NULL && s2 != NULL && s3 != NULL, "v3 component(s) missing declarations."); - g_operands.push_back( operand_info(s1,s2,s3,NULL) ); + g_operands.push_back( operand_info(s1,s2,s3,NULL,gpgpu_ctx) ); } -void add_4vector_operand( const char *d1, const char *d2, const char *d3, const char *d4 ) +void ptx_recognizer::add_4vector_operand( const char *d1, const char *d2, const char *d3, const char *d4 ) { PTX_PARSE_DPRINTF("add_4vector_operand"); const symbol *s1 = g_current_symbol_table->lookup(d1); @@ -774,9 +732,9 @@ void add_4vector_operand( const char *d1, const char *d2, const char *d3, const if ( s2 == null_op ) s2 = NULL; if ( s3 == null_op ) s3 = NULL; if ( s4 == null_op ) s4 = NULL; - g_operands.push_back( operand_info(s1,s2,s3,s4) ); + g_operands.push_back( operand_info(s1,s2,s3,s4,gpgpu_ctx) ); } -void add_8vector_operand( const char *d1, const char *d2, const char *d3, const char *d4,const char *d5,const char *d6,const char *d7,const char *d8 ) +void ptx_recognizer::add_8vector_operand( const char *d1, const char *d2, const char *d3, const char *d4,const char *d5,const char *d6,const char *d7,const char *d8 ) { PTX_PARSE_DPRINTF("add_8vector_operand"); const symbol *s1 = g_current_symbol_table->lookup(d1); @@ -796,16 +754,16 @@ void add_8vector_operand( const char *d1, const char *d2, const char *d3, const if ( s6 == null_op ) s6 = NULL; if ( s7 == null_op ) s7 = NULL; if ( s8 == null_op ) s8 = NULL; - g_operands.push_back( operand_info(s1,s2,s3,s4,s5,s6,s7,s8) ); + g_operands.push_back( operand_info(s1,s2,s3,s4,s5,s6,s7,s8,gpgpu_ctx) ); } -void add_builtin_operand( int builtin, int dim_modifier ) +void ptx_recognizer::add_builtin_operand( int builtin, int dim_modifier ) { PTX_PARSE_DPRINTF("add_builtin_operand"); - g_operands.push_back( operand_info(builtin,dim_modifier) ); + g_operands.push_back( operand_info(builtin,dim_modifier,gpgpu_ctx) ); } -void add_memory_operand() +void ptx_recognizer::add_memory_operand() { PTX_PARSE_DPRINTF("add_memory_operand"); assert( !g_operands.empty() ); @@ -813,7 +771,7 @@ void add_memory_operand() } /*TODO: add other memory locations*/ -void change_memory_addr_space(const char *identifier) +void ptx_recognizer::change_memory_addr_space(const char *identifier) { /*0 = N/A, not reading from memory *1 = global memory @@ -860,7 +818,7 @@ void change_memory_addr_space(const char *identifier) parse_assert(recognizedType, "Error: unrecognized memory type."); } -void change_operand_lohi( int lohi ) +void ptx_recognizer::change_operand_lohi( int lohi ) { /*0 = N/A, read entire operand *1 = lo, reading from lowest bits @@ -874,14 +832,14 @@ void change_operand_lohi( int lohi ) } -void set_immediate_operand_type () +void ptx_recognizer::set_immediate_operand_type () { PTX_PARSE_DPRINTF("set_immediate_operand_type"); assert( !g_operands.empty() ); g_operands.back().set_immediate_addr(); } -void change_double_operand_type( int operand_type ) +void ptx_recognizer::change_double_operand_type( int operand_type ) { /* *-3 = reg / reg (set instruction, but both get same value) @@ -913,7 +871,7 @@ void change_double_operand_type( int operand_type ) } -void change_operand_neg( ) +void ptx_recognizer::change_operand_neg( ) { PTX_PARSE_DPRINTF("change_operand_neg"); assert( !g_operands.empty() ); @@ -922,53 +880,53 @@ void change_operand_neg( ) } -void add_literal_int( int value ) +void ptx_recognizer::add_literal_int( int value ) { PTX_PARSE_DPRINTF("add_literal_int"); - g_operands.push_back( operand_info(value) ); + g_operands.push_back( operand_info(value,gpgpu_ctx) ); } -void add_literal_float( float value ) +void ptx_recognizer::add_literal_float( float value ) { PTX_PARSE_DPRINTF("add_literal_float"); - g_operands.push_back( operand_info(value) ); + g_operands.push_back( operand_info(value,gpgpu_ctx) ); } -void add_literal_double( double value ) +void ptx_recognizer::add_literal_double( double value ) { PTX_PARSE_DPRINTF("add_literal_double"); - g_operands.push_back( operand_info(value) ); + g_operands.push_back( operand_info(value,gpgpu_ctx) ); } -void add_scalar_operand( const char *identifier ) +void ptx_recognizer::add_scalar_operand( const char *identifier ) { PTX_PARSE_DPRINTF("add_scalar_operand"); const symbol *s = g_current_symbol_table->lookup(identifier); if ( s == NULL ) { if ( g_opcode == BRA_OP || g_opcode == CALLP_OP) { // forward branch target... - s = g_current_symbol_table->add_variable(identifier,NULL,0,g_filename,ptx_lineno); + s = g_current_symbol_table->add_variable(identifier,NULL,0,gpgpu_ctx->g_filename,ptx_get_lineno(scanner)); } else { std::string msg = std::string("operand \"") + identifier + "\" has no declaration."; parse_error( msg.c_str() ); } } - g_operands.push_back( operand_info(s) ); + g_operands.push_back( operand_info(s,gpgpu_ctx) ); } -void add_neg_pred_operand( const char *identifier ) +void ptx_recognizer::add_neg_pred_operand( const char *identifier ) { PTX_PARSE_DPRINTF("add_neg_pred_operand"); const symbol *s = g_current_symbol_table->lookup(identifier); if ( s == NULL ) { - s = g_current_symbol_table->add_variable(identifier,NULL,1,g_filename,ptx_lineno); + s = g_current_symbol_table->add_variable(identifier,NULL,1,gpgpu_ctx->g_filename,ptx_get_lineno(scanner)); } - operand_info op(s); + operand_info op(s, gpgpu_ctx); op.set_neg_pred(); g_operands.push_back( op ); } -void add_address_operand( const char *identifier, int offset ) +void ptx_recognizer::add_address_operand( const char *identifier, int offset ) { PTX_PARSE_DPRINTF("add_address_operand"); const symbol *s = g_current_symbol_table->lookup(identifier); @@ -976,28 +934,28 @@ void add_address_operand( const char *identifier, int offset ) std::string msg = std::string("operand \"") + identifier + "\" has no declaration."; parse_error( msg.c_str() ); } - g_operands.push_back( operand_info(s,offset) ); + g_operands.push_back( operand_info(s,offset,gpgpu_ctx) ); } -void add_address_operand2( int offset ) +void ptx_recognizer::add_address_operand2( int offset ) { PTX_PARSE_DPRINTF("add_address_operand"); - g_operands.push_back( operand_info((unsigned)offset) ); + g_operands.push_back( operand_info((unsigned)offset,gpgpu_ctx) ); } -void add_array_initializer() +void ptx_recognizer::add_array_initializer() { g_last_symbol->add_initializer(g_operands); } -void add_version_info( float ver, unsigned ext ) +void ptx_recognizer::add_version_info( float ver, unsigned ext ) { g_global_symbol_table->set_ptx_version(ver,ext); } -void add_file( unsigned num, const char *filename ) +void ptx_recognizer::add_file( unsigned num, const char *filename ) { - if( g_filename == NULL ) { + if( gpgpu_ctx->g_filename == NULL ) { char *b = strdup(filename); char *l=b; char *n=b; @@ -1013,7 +971,7 @@ void add_file( unsigned num, const char *filename ) char *q = strtok(NULL,"."); if( q && !strcmp(q,"cu") ) { - g_filename = strdup(buf); + gpgpu_ctx->g_filename = strdup(buf); } free( b ); @@ -1022,44 +980,44 @@ void add_file( unsigned num, const char *filename ) g_current_symbol_table = g_global_symbol_table; } -void *reset_symtab() +void * ptx_recognizer::reset_symtab() { void *result = g_current_symbol_table; g_current_symbol_table = g_global_symbol_table; return result; } -void set_symtab(void*symtab) +void ptx_recognizer::set_symtab(void*symtab) { g_current_symbol_table = (symbol_table*)symtab; } -void add_pragma( const char *str ) +void ptx_recognizer::add_pragma( const char *str ) { printf("GPGPU-Sim PTX: Warning -- ignoring pragma '%s'\n", str ); } -void version_header(double a) {} //intentional dummy function +void ptx_recognizer::version_header(double a) {} //intentional dummy function -void target_header(char* a) +void ptx_recognizer::target_header(char* a) { g_global_symbol_table->set_sm_target(a,NULL,NULL); } -void target_header2(char* a, char* b) +void ptx_recognizer::target_header2(char* a, char* b) { g_global_symbol_table->set_sm_target(a,b,NULL); } -void target_header3(char* a, char* b, char* c) +void ptx_recognizer::target_header3(char* a, char* b, char* c) { g_global_symbol_table->set_sm_target(a,b,c); } -void maxnt_id(int x, int y, int z) { +void ptx_recognizer::maxnt_id(int x, int y, int z) { g_func_info->set_maxnt_id(x * y * z); } -void func_header(const char* a) {} //intentional dummy function -void func_header_info(const char* a) {} //intentional dummy function -void func_header_info_int(const char* a, int b) {} //intentional dummy function +void ptx_recognizer::func_header(const char* a) {} //intentional dummy function +void ptx_recognizer::func_header_info(const char* a) {} //intentional dummy function +void ptx_recognizer::func_header_info_int(const char* a, int b) {} //intentional dummy function diff --git a/src/cuda-sim/ptx_parser.h b/src/cuda-sim/ptx_parser.h index 7b6e3a2..11a3d20 100644 --- a/src/cuda-sim/ptx_parser.h +++ b/src/cuda-sim/ptx_parser.h @@ -29,77 +29,159 @@ #define ptx_parser_INCLUDED #include "../abstract_hardware_model.h" -extern const char *g_filename; -extern int g_error_detected; +#include "ptx_ir.h" -#ifdef __cplusplus -class symbol_table* init_parser(const char*); -const class ptx_instruction *ptx_instruction_lookup( const char *filename, unsigned linenumber ); -#endif +class gpgpu_context; +typedef void * yyscan_t; +class ptx_recognizer { + public: + ptx_recognizer( gpgpu_context* ctx ) : g_return_var(ctx) { + scanner = NULL; + g_size = -1; + g_add_identifier_cached__identifier = NULL; + g_alignment_spec = -1; + g_var_type = NULL; + g_opcode = -1; + g_space_spec = undefined_space; + g_ptr_spec = undefined_space; + g_scalar_type_spec = -1; + g_vector_spec = -1; + g_extern_spec = 0; + g_func_decl = 0; + g_ident_add_uid = 0; + g_const_alloc = 1; + g_max_regs_per_thread = 0; + g_global_symbol_table = NULL; + g_current_symbol_table = NULL; + g_last_symbol = NULL; + g_error_detected = 0; + g_entry_func_param_index=0; + g_func_info = NULL; + g_debug_ir_generation=false; + gpgpu_ctx = ctx; + } + // global list + yyscan_t scanner; +#define PTX_LINEBUF_SIZE (4*1024) + char linebuf[PTX_LINEBUF_SIZE]; + unsigned col; + int g_size; + char *g_add_identifier_cached__identifier; + int g_add_identifier_cached__array_dim; + int g_add_identifier_cached__array_ident; + int g_alignment_spec; + // variable declaration stuff: + type_info *g_var_type; + // instruction definition stuff: + const symbol *g_pred; + int g_neg_pred; + int g_pred_mod; + symbol *g_label; + int g_opcode; + std::list<operand_info> g_operands; + std::list<int> g_options; + std::list<int> g_wmma_options; + std::list<int> g_scalar_type; + // type specifier stuff: + memory_space_t g_space_spec; + memory_space_t g_ptr_spec; + int g_scalar_type_spec; + int g_vector_spec; + int g_extern_spec; + int g_func_decl; + int g_ident_add_uid; + unsigned g_const_alloc; + unsigned g_max_regs_per_thread; + symbol_table *g_global_symbol_table; + symbol_table *g_current_symbol_table; + symbol *g_last_symbol; + std::list<ptx_instruction*> g_instructions; + int g_error_detected; + unsigned g_entry_func_param_index; + function_info *g_func_info; + operand_info g_return_var; + bool g_debug_ir_generation; + int g_entry_point; + const struct core_config *g_shader_core_config; + std::map<std::string,std::map<unsigned,const ptx_instruction*> > g_inst_lookup; + // the program intermediate representation... + std::map<std::string,symbol_table*> g_sym_name_to_symbol_table; + // backward pointer + class gpgpu_context* gpgpu_ctx; + + // member function list + void init_directive_state(); + void init_instruction_state(); + void start_function( int entry_point ); + void add_function_name( const char *fname ); + void add_directive(); + void end_function(); + void add_identifier( const char *s, int array_dim, unsigned array_ident ); + void add_function_arg(); + void add_scalar_type_spec( int type_spec ); + void add_scalar_operand( const char *identifier ); + void add_neg_pred_operand( const char *identifier ); + void add_variables(); + void set_variable_type(); + void add_opcode( int opcode ); + void add_pred( const char *identifier, int negate, int predModifier ); + void add_1vector_operand( const char *d1 ); + void add_2vector_operand( const char *d1, const char *d2 ); + void add_3vector_operand( const char *d1, const char *d2, const char *d3 ); + void add_4vector_operand( const char *d1, const char *d2, const char *d3, const char *d4 ); + void add_8vector_operand( const char *d1, const char *d2, const char *d3, const char *d4 ,const char *d5,const char *d6,const char *d7,const char *d8); + void add_option(int option ); + void add_wmma_option(int option ); + void add_builtin_operand( int builtin, int dim_modifier ); + void add_memory_operand( ); + void add_literal_int( int value ); + void add_literal_float( float value ); + void add_literal_double( double value ); + void add_address_operand( const char *identifier, int offset ); + void add_address_operand2( int offset ); + void add_label( const char *idenfiier ); + void add_vector_spec(int spec ); + void add_space_spec( enum _memory_space_t spec, int value ); + void add_ptr_spec( enum _memory_space_t spec ); + void add_extern_spec(); + void add_instruction(); + void set_return(); + void add_alignment_spec( int spec ); + void add_array_initializer(); + void add_file( unsigned num, const char *filename ); + void add_version_info( float ver, unsigned ext); + void *reset_symtab(); + void set_symtab(void*); + void add_pragma( const char *str ); + void func_header(const char* a); + void func_header_info(const char* a); + void func_header_info_int(const char* a, int b); + void add_constptr(const char* identifier1, const char* identifier2, int offset); + void target_header(char* a); + void target_header2(char* a, char* b); + void target_header3(char* a, char* b, char* c); + void add_double_operand( const char *d1, const char *d2 ); + void change_memory_addr_space( const char *identifier ); + void change_operand_lohi( int lohi ); + void change_double_operand_type( int addr_type ); + void change_operand_neg( ); + void set_immediate_operand_type( ); + void version_header(double a); + void maxnt_id(int x, int y, int z); + void parse_error_impl( const char *file, unsigned line, const char *msg, ... ); + void parse_assert_impl( int test_value, const char *file, unsigned line, const char *msg, ... ); + //Jin: handle instructino group for cdp + void start_inst_group(); + void end_inst_group(); + bool check_for_duplicates( const char *identifier ); + void read_parser_environment_variables(); + void set_ptx_warp_size(const struct core_config * warp_size); + const class ptx_instruction *ptx_instruction_lookup( const char *filename, unsigned linenumber ); + +}; const char *decode_token( int type ); void read_parser_environment_variables(); -void start_function( int entry_point ); -void add_function_name( const char *fname ); -void init_directive_state(); -void add_directive(); -void end_function(); -void add_identifier( const char *s, int array_dim, unsigned array_ident ); -void add_function_arg(); -void add_scalar_type_spec( int type_spec ); -void add_scalar_operand( const char *identifier ); -void add_neg_pred_operand( const char *identifier ); -void add_variables(); -void set_variable_type(); -void add_opcode( int opcode ); -void add_pred( const char *identifier, int negate, int predModifier ); -void add_1vector_operand( const char *d1 ); -void add_2vector_operand( const char *d1, const char *d2 ); -void add_3vector_operand( const char *d1, const char *d2, const char *d3 ); -void add_4vector_operand( const char *d1, const char *d2, const char *d3, const char *d4 ); -void add_8vector_operand( const char *d1, const char *d2, const char *d3, const char *d4 ,const char *d5,const char *d6,const char *d7,const char *d8); -void add_option(int option ); -void add_wmma_option(int option ); -void add_builtin_operand( int builtin, int dim_modifier ); -void add_memory_operand( ); -void add_literal_int( int value ); -void add_literal_float( float value ); -void add_literal_double( double value ); -void add_address_operand( const char *identifier, int offset ); -void add_address_operand2( int offset ); -void add_label( const char *idenfiier ); -void add_vector_spec(int spec ); -void add_space_spec( enum _memory_space_t spec, int value ); -void add_ptr_spec( enum _memory_space_t spec ); -void add_extern_spec(); -void add_instruction(); -void set_return(); -void add_alignment_spec( int spec ); -void add_array_initializer(); -void add_file( unsigned num, const char *filename ); -void add_version_info( float ver, unsigned ext); -void *reset_symtab(); -void set_symtab(void*); -void add_pragma( const char *str ); -void func_header(const char* a); -void func_header_info(const char* a); -void func_header_info_int(const char* a, int b); -void add_constptr(const char* identifier1, const char* identifier2, int offset); -void target_header(char* a); -void target_header2(char* a, char* b); -void target_header3(char* a, char* b, char* c); -void add_double_operand( const char *d1, const char *d2 ); -void change_memory_addr_space( const char *identifier ); -void change_operand_lohi( int lohi ); -void change_double_operand_type( int addr_type ); -void change_operand_neg( ); -void set_immediate_operand_type( ); -void version_header(double a); -void maxnt_id(int x, int y, int z); - -//Jin: handle instructino group for cdp -void start_inst_group(); -void end_inst_group(); #define NON_ARRAY_IDENTIFIER 1 #define ARRAY_IDENTIFIER_NO_DIM 2 diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc index 820287d..949ee66 100644 --- a/src/cuda-sim/ptx_sim.cc +++ b/src/cuda-sim/ptx_sim.cc @@ -28,23 +28,25 @@ #include "ptx_sim.h" #include <string> #include "ptx_ir.h" +class ptx_recognizer; +typedef void * yyscan_t; #include "ptx.tab.h" #include "../gpgpu-sim/gpu-sim.h" #include "../gpgpu-sim/shader.h" +#include "../../libcuda/gpgpu_context.h" void feature_not_implemented( const char *f ); -std::set<unsigned long long> g_ptx_cta_info_sm_idx_used; -unsigned long long g_ptx_cta_info_uid = 1; -ptx_cta_info::ptx_cta_info( unsigned sm_idx ) +ptx_cta_info::ptx_cta_info( unsigned sm_idx, gpgpu_context* ctx ) { - assert( g_ptx_cta_info_sm_idx_used.find(sm_idx) == g_ptx_cta_info_sm_idx_used.end() ); - g_ptx_cta_info_sm_idx_used.insert(sm_idx); + assert( ctx->func_sim->g_ptx_cta_info_sm_idx_used.find(sm_idx) == ctx->func_sim->g_ptx_cta_info_sm_idx_used.end() ); + ctx->func_sim->g_ptx_cta_info_sm_idx_used.insert(sm_idx); m_sm_idx = sm_idx; - m_uid = g_ptx_cta_info_uid++; + m_uid = (ctx->g_ptx_cta_info_uid)++; m_bar_threads = 0; + gpgpu_ctx = ctx; } void ptx_cta_info::add_thread( ptx_thread_info *thd ) @@ -164,18 +166,16 @@ void ptx_warp_info::reset_done_threads() m_done_threads = 0; } -unsigned g_ptx_thread_info_uid_next=1; -unsigned g_ptx_thread_info_delete_count=0; ptx_thread_info::~ptx_thread_info() { - g_ptx_thread_info_delete_count++; + m_gpu->gpgpu_ctx->func_sim->g_ptx_thread_info_delete_count++; } ptx_thread_info::ptx_thread_info( kernel_info_t &kernel ) : m_kernel(kernel) { - m_uid = g_ptx_thread_info_uid_next++; + m_uid = kernel.entry()->gpgpu_ctx->func_sim->g_ptx_thread_info_uid_next++; m_core = NULL; m_barrier_num = -1; m_at_barrier = false; @@ -222,7 +222,7 @@ void ptx_thread_info::set_done() { assert( !m_at_barrier ); m_thread_done = true; - m_cycle_done = gpu_sim_cycle; + m_cycle_done = m_gpu->gpu_sim_cycle; } unsigned ptx_thread_info::get_builtin( int builtin_id, unsigned dim_mod ) @@ -230,15 +230,15 @@ unsigned ptx_thread_info::get_builtin( int builtin_id, unsigned dim_mod ) assert( m_valid ); switch ((builtin_id&0xFFFF)) { case CLOCK_REG: - return (unsigned)(gpu_sim_cycle + gpu_tot_sim_cycle); + return (unsigned)(m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); case CLOCK64_REG: abort(); // change return value to unsigned long long? // GPGPUSim clock is 4 times slower - multiply by 4 - return (gpu_sim_cycle + gpu_tot_sim_cycle)*4; + return (m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle)*4; case HALFCLOCK_ID: // GPGPUSim clock is 4 times slower - multiply by 4 // Hardware clock counter is incremented at half the shader clock frequency - divide by 2 (Henry '10) - return (gpu_sim_cycle + gpu_tot_sim_cycle)*2; + return (m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle)*2; case CTAID_REG: assert( dim_mod < 3 ); if( dim_mod == 0 ) return m_ctaid.x; @@ -421,9 +421,9 @@ bool ptx_thread_info::callstack_pop() assert( !((rv_src != NULL) ^ (rv_dst != NULL)) ); // ensure caller and callee agree on whether there is a return value // read return value from callee frame - arg_buffer_t buffer; + arg_buffer_t buffer(m_gpu->gpgpu_ctx); if( rv_src != NULL ) - buffer = copy_arg_to_buffer(this, operand_info(rv_src), rv_dst ); + buffer = copy_arg_to_buffer(this, operand_info(rv_src, m_gpu->gpgpu_ctx), rv_dst ); m_symbol_table = m_callstack.back().m_symbol_table; m_NPC = m_callstack.back().m_PC; @@ -455,9 +455,9 @@ bool ptx_thread_info::callstack_pop_plus() assert( !((rv_src != NULL) ^ (rv_dst != NULL)) ); // ensure caller and callee agree on whether there is a return value // read return value from callee frame - arg_buffer_t buffer; + arg_buffer_t buffer(m_gpu->gpgpu_ctx); if( rv_src != NULL ) - buffer = copy_arg_to_buffer(this, operand_info(rv_src), rv_dst ); + buffer = copy_arg_to_buffer(this, operand_info(rv_src, m_gpu->gpgpu_ctx), rv_dst ); m_symbol_table = m_callstack.back().m_symbol_table; m_NPC = m_callstack.back().m_PC; diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h index d226fbe..c2b3cc8 100644 --- a/src/cuda-sim/ptx_sim.h +++ b/src/cuda-sim/ptx_sim.h @@ -164,7 +164,7 @@ class ptx_thread_info; class ptx_cta_info { public: - ptx_cta_info( unsigned sm_idx ); + ptx_cta_info( unsigned sm_idx, gpgpu_context* ctx ); void add_thread( ptx_thread_info *thd ); unsigned num_threads() const; void check_cta_thread_status_and_reset(); @@ -176,6 +176,8 @@ public: void reset_bar_threads(); private: + // backward pointer + class gpgpu_context* gpgpu_ctx; unsigned m_bar_threads; unsigned long long m_uid; unsigned m_sm_idx; @@ -341,6 +343,7 @@ public: dim3 get_ctaid() const { return m_ctaid; } dim3 get_tid() const { return m_tid; } + dim3 get_ntid() const { return m_ntid; } class gpgpu_sim *get_gpu() { return (gpgpu_sim*)m_gpu;} unsigned get_hw_tid() const { return m_hw_tid;} unsigned get_hw_ctaid() const { return m_hw_ctaid;} diff --git a/src/cuda-sim/ptxinfo.l b/src/cuda-sim/ptxinfo.l index 33c2748..51371e3 100644 --- a/src/cuda-sim/ptxinfo.l +++ b/src/cuda-sim/ptxinfo.l @@ -31,17 +31,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %option noyywrap %option yylineno %option prefix="ptxinfo_" + +%option bison-bridge +%option reentrant + %{ +#include "ptx_loader.h" #include "ptxinfo.tab.h" #include <string.h> +#include "../../libcuda/gpgpu_context.h" #define LINEBUF_SIZE 1024 -char ptxinfo_linebuf[LINEBUF_SIZE]; -unsigned ptxinfo_col = 0; -#define TC if( (ptxinfo_lineno == 1) && ((ptxinfo_col + strlen(ptxinfo_text)) < LINEBUF_SIZE) ) { \ - strncpy(ptxinfo_linebuf+ptxinfo_col,ptxinfo_text,strlen(ptxinfo_text)); \ +#define TC if( (yylineno == 1) && (ptxinfo->col + strlen(yytext) < LINEBUF_SIZE) ) { \ + strncpy(ptxinfo->linebuf+ptxinfo->col,yytext,strlen(yytext)); \ } \ - ptxinfo_col+=strlen(ptxinfo_text); + ptxinfo->col+=strlen(yytext); +#define YY_DECL int ptxinfo_lex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner, ptxinfo_data* ptxinfo) %} %% @@ -61,12 +67,12 @@ unsigned ptxinfo_col = 0; "for" TC; return FOR; "textures" TC; return TEXTURES; "error : Duplicate definition of" TC; return DUPLICATE; -"function" TC; ptxinfo_lval.string_value = strdup(yytext); return FUNCTION; -"variable" TC; ptxinfo_lval.string_value = strdup(yytext); return VARIABLE; +"function" TC; yylval->string_value = strdup(yytext); return FUNCTION; +"variable" TC; yylval->string_value = strdup(yytext); return VARIABLE; "fatal : Ptx assembly aborted due to errors" TC; return FATAL; -[_A-Za-z$%][_0-9A-Za-z$]* TC; ptxinfo_lval.string_value = strdup(yytext); return IDENTIFIER; -[-]{0,1}[0-9]+ TC; ptxinfo_lval.int_value = atoi(yytext); return INT_OPERAND; +[_A-Za-z$%][_0-9A-Za-z$]* TC; yylval->string_value = strdup(yytext); return IDENTIFIER; +[-]{0,1}[0-9]+ TC; yylval->int_value = atoi(yytext); return INT_OPERAND; "+" TC; return PLUS; "," TC; return COMMA; @@ -78,26 +84,23 @@ unsigned ptxinfo_col = 0; " " TC; "\t" TC; -\n.* ptxinfo_col=0; strncpy(ptxinfo_linebuf, yytext + 1, 1024); yyless( 1 ); +\n.* ptxinfo->col=0; strncpy(ptxinfo->linebuf, yytext + 1, 1024); yyless( 1 ); %% -extern int g_ptxinfo_error_detected; -extern const char *g_filename; -extern const char *g_ptxinfo_filename; - -int ptxinfo_error( const char *s ) +int ptxinfo_error(yyscan_t yyscanner, ptxinfo_data* ptxinfo, const char* msg) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; int i; - g_ptxinfo_error_detected = 1; + ptxinfo->gpgpu_ctx->func_sim->g_ptxinfo_error_detected = 1; fflush(stdout); printf("GPGPU-Sim: ERROR while parsing output of ptxas (used to capture resource usage information)\n"); - if( s != NULL ) - printf("GPGPU-Sim: %s (%s:%u) Syntax error:\n\n", g_filename, g_ptxinfo_filename, ptxinfo_lineno ); - printf(" %s\n", ptxinfo_linebuf ); + if( msg != NULL ) + printf("GPGPU-Sim: %s (%s:%u) Syntax error:\n\n", ptxinfo->gpgpu_ctx->g_filename, ptxinfo->g_ptxinfo_filename, yylineno ); + printf(" %s\n", ptxinfo->linebuf ); printf(" "); - for( i=0; i < ptxinfo_col-1; i++ ) { - if( ptxinfo_linebuf[i] == '\t' ) printf("\t"); + for( i=0; i < ptxinfo->col-1; i++ ) { + if( ptxinfo->linebuf[i] == '\t' ) printf("\t"); else printf(" "); } diff --git a/src/cuda-sim/ptxinfo.y b/src/cuda-sim/ptxinfo.y index d241d8c..b303958 100644 --- a/src/cuda-sim/ptxinfo.y +++ b/src/cuda-sim/ptxinfo.y @@ -27,6 +27,17 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +%{ +typedef void * yyscan_t; +#include "ptx_loader.h" +%} + +%define api.pure full +%parse-param {yyscan_t scanner} +%parse-param {ptxinfo_data* ptxinfo} +%lex-param {yyscan_t scanner} +%lex-param {ptxinfo_data* ptxinfo} + %union { int int_value; char * string_value; @@ -66,15 +77,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. static unsigned g_declared; static unsigned g_system; - int ptxinfo_lex(void); - void ptxinfo_addinfo(); + int ptxinfo_lex(YYSTYPE * yylval_param, yyscan_t yyscanner, ptxinfo_data* ptxinfo); + void yyerror(yyscan_t yyscanner, ptxinfo_data* ptxinfo, const char* msg); void ptxinfo_function(const char *fname ); void ptxinfo_regs( unsigned nregs ); void ptxinfo_lmem( unsigned declared, unsigned system ); void ptxinfo_gmem( unsigned declared, unsigned system ); void ptxinfo_smem( unsigned declared, unsigned system ); void ptxinfo_cmem( unsigned nbytes, unsigned bank ); - int ptxinfo_error(const char*); void ptxinfo_linenum( unsigned ); void ptxinfo_dup_type( const char* ); %} @@ -93,7 +103,7 @@ line: HEADER INFO COLON line_info ; line_info: function_name - | function_info { ptxinfo_addinfo(); } + | function_info { ptxinfo->ptxinfo_addinfo(); } | gmem_info ; diff --git a/src/debug.cc b/src/debug.cc index ae15760..c00ff9e 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -36,28 +36,7 @@ #include <stdio.h> #include <string.h> -class watchpoint_event { -public: - watchpoint_event() - { - m_thread=NULL; - m_inst=NULL; - } - watchpoint_event(const ptx_thread_info *thd, const ptx_instruction *pI) - { - m_thread=thd; - m_inst = pI; - } - const ptx_thread_info *thread() const { return m_thread; } - const ptx_instruction *inst() const { return m_inst; } -private: - const ptx_thread_info *m_thread; - const ptx_instruction *m_inst; -}; - -std::map<unsigned,watchpoint_event> g_watchpoint_hits; - -void hit_watchpoint( unsigned watchpoint_num, ptx_thread_info *thd, const ptx_instruction *pI ) +void gpgpu_sim::hit_watchpoint( unsigned watchpoint_num, ptx_thread_info *thd, const ptx_instruction *pI ) { g_watchpoint_hits[watchpoint_num]=watchpoint_event(thd,pI); } diff --git a/src/debug.h b/src/debug.h index 1277494..4e79a9f 100644 --- a/src/debug.h +++ b/src/debug.h @@ -83,11 +83,8 @@ private: unsigned m_value; }; -extern int gpgpu_ptx_instruction_classification ; - class ptx_thread_info; class ptx_instruction; bool thread_at_brkpt( ptx_thread_info *thd_info, const class brk_pt &b ); -void hit_watchpoint( unsigned watchpoint_num, ptx_thread_info *thd, const ptx_instruction *pI ); #endif diff --git a/src/gpgpu-sim/Makefile b/src/gpgpu-sim/Makefile index f10a8a4..4994577 100644 --- a/src/gpgpu-sim/Makefile +++ b/src/gpgpu-sim/Makefile @@ -53,6 +53,8 @@ else CXXFLAGS += endif +CXXFLAGS += -I$(CUDA_INSTALL_PATH)/include + POWER_FLAGS= ifneq ($(GPGPUSIM_POWER_MODEL),) POWER_FLAGS = -I$(GPGPUSIM_POWER_MODEL) -DGPGPUSIM_POWER_MODEL diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 192cb65..d443d79 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -41,13 +41,14 @@ int PRINT_CYCLE = 0; template class fifo_pipeline<mem_fetch>; template class fifo_pipeline<dram_req_t>; -dram_t::dram_t( unsigned int partition_id, const struct memory_config *config, memory_stats_t *stats, - memory_partition_unit *mp ) +dram_t::dram_t( unsigned int partition_id, const memory_config *config, memory_stats_t *stats, + memory_partition_unit *mp, gpgpu_sim* gpu ) { id = partition_id; m_memory_partition_unit = mp; m_stats = stats; m_config = config; + m_gpu = gpu; //rowblp access_num=0; @@ -191,11 +192,12 @@ unsigned int dram_t::queue_limit() const } -dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy) +dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_indexing_policy, class gpgpu_sim* gpu) { txbytes = 0; dqbytes = 0; data = mf; + m_gpu = gpu; const addrdec_t &tlx = mf->get_tlx_addr(); @@ -226,9 +228,9 @@ dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_i col = tlx.col; nbytes = mf->get_data_size(); - timestamp = gpu_tot_sim_cycle + gpu_sim_cycle; + timestamp = m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle; addr = mf->get_addr(); - insertion_time = (unsigned) gpu_sim_cycle; + insertion_time = (unsigned) m_gpu->gpu_sim_cycle; rw = data->get_is_write()?WRITE:READ; } @@ -236,9 +238,9 @@ void dram_t::push( class mem_fetch *data ) { assert(id == data->get_tlx_addr().chip); // Ensure request is in correct memory partition - dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy); + dram_req_t *mrq = new dram_req_t(data,m_config->nbk,m_config->dram_bnk_indexing_policy,m_memory_partition_unit->get_mgpu()); - data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + data->set_status(IN_PARTITION_MC_INTERFACE_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); mrqq->push(mrq); // stats... @@ -259,7 +261,7 @@ void dram_t::scheduler_fifo() if (!mrqq->empty()) { unsigned int bkn; dram_req_t *head_mrqq = mrqq->top(); - head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + head_mrqq->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); bkn = head_mrqq->bk; if (!bk[bkn]->mrq) bk[bkn]->mrq = mrqq->pop(); @@ -283,7 +285,7 @@ void dram_t::cycle() if (cmd->dqbytes >= cmd->nbytes) { mem_fetch *data = cmd->data; - data->set_status(IN_PARTITION_MC_RETURNQ,gpu_sim_cycle+gpu_tot_sim_cycle); + data->set_status(IN_PARTITION_MC_RETURNQ,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); if( data->get_access_type() != L1_WRBK_ACC && data->get_access_type() != L2_WRBK_ACC ) { data->set_reply(); returnq->push(data); @@ -566,7 +568,7 @@ bool dram_t::issue_col_command(int j) bool issued = false; unsigned grp = get_bankgrp_number(j); if (bk[j]->mrq) { //if currently servicing a memory request - bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle); + bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); // correct row activated for a READ if ( !issued && !CCDc && !bk[j]->RCDc && !(bkgrp[grp]->CCDLc) && @@ -654,7 +656,7 @@ bool dram_t::issue_row_command(int j) bool issued = false; unsigned grp = get_bankgrp_number(j); if (bk[j]->mrq) { //if currently servicing a memory request - bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,gpu_sim_cycle+gpu_tot_sim_cycle); + bk[j]->mrq->data->set_status(IN_PARTITION_DRAM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); // bank is idle //else if ( !issued && !RRDc && diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 1ab0153..0bd9725 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -48,7 +48,7 @@ class dram_req_t { public: - dram_req_t( class mem_fetch *data , unsigned banks, unsigned dram_bnk_indexing_policy); + dram_req_t( class mem_fetch *data , unsigned banks, unsigned dram_bnk_indexing_policy, class gpgpu_sim* gpu); unsigned int row; unsigned int col; @@ -62,6 +62,7 @@ public: unsigned long long int addr; unsigned int insertion_time; class mem_fetch * data; + class gpgpu_sim * m_gpu; }; struct bankgrp_t @@ -105,12 +106,13 @@ enum bank_grp_bits_position{ }; class mem_fetch; +class memory_config; class dram_t { public: - dram_t( unsigned int parition_id, const struct memory_config *config, class memory_stats_t *stats, - class memory_partition_unit *mp ); + dram_t( unsigned int parition_id, const memory_config *config, class memory_stats_t *stats, + class memory_partition_unit *mp, class gpgpu_sim* gpu ); bool full(bool is_write) const; void print( FILE* simFile ) const; @@ -129,6 +131,7 @@ public: void dram_log (int task); class memory_partition_unit *m_memory_partition_unit; + class gpgpu_sim* m_gpu; unsigned int id; // Power Model @@ -143,7 +146,7 @@ public: - const struct memory_config *m_config; + const memory_config *m_config; private: bankgrp_t **bkgrp; diff --git a/src/gpgpu-sim/dram_sched.cc b/src/gpgpu-sim/dram_sched.cc index ff50050..6ee6271 100644 --- a/src/gpgpu-sim/dram_sched.cc +++ b/src/gpgpu-sim/dram_sched.cc @@ -84,13 +84,13 @@ void frfcfs_scheduler::add_req( dram_req_t *req ) void frfcfs_scheduler::data_collection(unsigned int bank) { - if (gpu_sim_cycle > row_service_timestamp[bank]) { - curr_row_service_time[bank] = gpu_sim_cycle - row_service_timestamp[bank]; + if (m_dram->m_gpu->gpu_sim_cycle > row_service_timestamp[bank]) { + curr_row_service_time[bank] = m_dram->m_gpu->gpu_sim_cycle - row_service_timestamp[bank]; if (curr_row_service_time[bank] > m_stats->max_servicetime2samerow[m_dram->id][bank]) m_stats->max_servicetime2samerow[m_dram->id][bank] = curr_row_service_time[bank]; } curr_row_service_time[bank] = 0; - row_service_timestamp[bank] = gpu_sim_cycle; + row_service_timestamp[bank] = m_dram->m_gpu->gpu_sim_cycle; if (m_stats->concurrent_row_access[m_dram->id][bank] > m_stats->max_conc_access2samerow[m_dram->id][bank]) { m_stats->max_conc_access2samerow[m_dram->id][bank] = m_stats->concurrent_row_access[m_dram->id][bank]; } @@ -215,7 +215,7 @@ void dram_t::scheduler_frfcfs() m_stats->total_n_reads++; } - req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + req->data->set_status(IN_PARTITION_MC_INPUT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); sched->add_req(req); } @@ -228,14 +228,14 @@ void dram_t::scheduler_frfcfs() req = sched->schedule(b, bk[b]->curr_row); if ( req ) { - req->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + req->data->set_status(IN_PARTITION_MC_BANK_ARB_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); prio = (prio+1)%m_config->nbk; bk[b]->mrq = req; if (m_config->gpgpu_memlatency_stat) { - mrq_latency = gpu_sim_cycle + gpu_tot_sim_cycle - bk[b]->mrq->timestamp; + mrq_latency = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle - bk[b]->mrq->timestamp; m_stats->tot_mrq_latency += mrq_latency; m_stats->tot_mrq_num++; - bk[b]->mrq->timestamp = gpu_tot_sim_cycle + gpu_sim_cycle; + bk[b]->mrq->timestamp =m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle; m_stats->mrq_lat_table[LOGB2(mrq_latency)]++; if (mrq_latency > m_stats->max_mrq_latency) { m_stats->max_mrq_latency = mrq_latency; diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 370f6e6..1705821 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -26,6 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "gpu-cache.h" +#include "gpu-sim.h" #include "stat-tool.h" #include <assert.h> @@ -1250,7 +1251,8 @@ data_cache::wr_miss_wa_naive( new_addr_type addr, false, // Now performing a read mf->get_access_warp_mask(), mf->get_access_byte_mask(), - mf->get_access_sector_mask()); + mf->get_access_sector_mask(), + m_gpu->gpgpu_ctx); mem_fetch *n_mf = new mem_fetch( *ma, NULL, @@ -1258,7 +1260,8 @@ data_cache::wr_miss_wa_naive( new_addr_type addr, mf->get_wid(), mf->get_sid(), mf->get_tpc(), - mf->get_mem_config()); + mf->get_mem_config(), + m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); bool do_miss = false; bool wb = false; @@ -1276,7 +1279,7 @@ data_cache::wr_miss_wa_naive( new_addr_type addr, if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { assert(status == MISS); //SECTOR_MISS and HIT_RESERVED should not send write back mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, - m_wrbk_type,evicted.m_modified_size,true); + m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1320,7 +1323,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, // (already modified lower level) if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, - m_wrbk_type,evicted.m_modified_size,true); + m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1363,7 +1366,8 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, false, // Now performing a read mf->get_access_warp_mask(), mf->get_access_byte_mask(), - mf->get_access_sector_mask()); + mf->get_access_sector_mask(), + m_gpu->gpgpu_ctx); mem_fetch *n_mf = new mem_fetch( *ma, NULL, @@ -1372,6 +1376,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), + m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle, NULL, mf); @@ -1395,7 +1400,7 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, // (already modified lower level) if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){ mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, - m_wrbk_type,evicted.m_modified_size,true); + m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1448,7 +1453,7 @@ data_cache::wr_miss_wa_lazy_fetch_on_read( new_addr_type addr, // (already modified lower level) if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, - m_wrbk_type,evicted.m_modified_size,true); + m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1533,7 +1538,7 @@ data_cache::rd_miss_base( new_addr_type addr, // (already modified lower level) if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){ mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, - m_wrbk_type,evicted.m_modified_size,true); + m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); } return MISS; diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 337f710..be33d96 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -1290,12 +1290,13 @@ public: data_cache( const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, mem_fetch_allocator *mfcreator, enum mem_fetch_status status, - mem_access_type wr_alloc_type, mem_access_type wrbk_type ) + mem_access_type wr_alloc_type, mem_access_type wrbk_type, class gpgpu_sim* gpu ) : baseline_cache(name,config,core_id,type_id,memport,status) { init( mfcreator ); m_wr_alloc_type = wr_alloc_type; m_wrbk_type = wrbk_type; + m_gpu=gpu; } virtual ~data_cache() {} @@ -1353,16 +1354,19 @@ protected: enum mem_fetch_status status, tag_array* new_tag_array, mem_access_type wr_alloc_type, - mem_access_type wrbk_type) + mem_access_type wrbk_type, + class gpgpu_sim* gpu ) : baseline_cache(name, config, core_id, type_id, memport,status, new_tag_array) { init( mfcreator ); m_wr_alloc_type = wr_alloc_type; m_wrbk_type = wrbk_type; + m_gpu=gpu; } mem_access_type m_wr_alloc_type; // Specifies type of write allocate request (e.g., L1 or L2) mem_access_type m_wrbk_type; // Specifies type of writeback request (e.g., L1 or L2) + class gpgpu_sim* m_gpu; //! A general function that takes the result of a tag_array probe // and performs the correspding functions based on the cache configuration @@ -1519,8 +1523,8 @@ class l1_cache : public data_cache { public: l1_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, - mem_fetch_allocator *mfcreator, enum mem_fetch_status status ) - : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L1_WR_ALLOC_R, L1_WRBK_ACC){} + mem_fetch_allocator *mfcreator, enum mem_fetch_status status, class gpgpu_sim* gpu ) + : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L1_WR_ALLOC_R, L1_WRBK_ACC, gpu){} virtual ~l1_cache(){} @@ -1538,10 +1542,11 @@ protected: mem_fetch_interface *memport, mem_fetch_allocator *mfcreator, enum mem_fetch_status status, - tag_array* new_tag_array ) + tag_array* new_tag_array, + class gpgpu_sim* gpu) : data_cache( name, config, - core_id,type_id,memport,mfcreator,status, new_tag_array, L1_WR_ALLOC_R, L1_WRBK_ACC ){} + core_id,type_id,memport,mfcreator,status, new_tag_array, L1_WR_ALLOC_R, L1_WRBK_ACC, gpu ){} }; @@ -1551,8 +1556,8 @@ class l2_cache : public data_cache { public: l2_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, - mem_fetch_allocator *mfcreator, enum mem_fetch_status status ) - : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L2_WR_ALLOC_R, L2_WRBK_ACC){} + mem_fetch_allocator *mfcreator, enum mem_fetch_status status, class gpgpu_sim* gpu ) + : data_cache(name,config,core_id,type_id,memport,mfcreator,status, L2_WR_ALLOC_R, L2_WRBK_ACC, gpu){} virtual ~l2_cache() {} diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 92d5366..622b8bd 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -65,6 +65,7 @@ #include "visualizer.h" #include "stats.h" #include "../cuda-sim/cuda_device_runtime.h" +#include "../../libcuda/gpgpu_context.h" #ifdef GPGPUSIM_POWER_MODEL #include "power_interface.h" @@ -83,23 +84,6 @@ class gpgpu_sim_wrapper {}; bool g_interactive_debugger_enabled=false; -unsigned long long gpu_sim_cycle = 0; -unsigned long long gpu_tot_sim_cycle = 0; -unsigned long long elapsed_cycles_sm_tot = 0; //this is a equivalent metric generated as nvprof. that only counts when SM is active - - -// performance counter for stalls due to congestion. -unsigned int gpu_stall_dramfull = 0; -unsigned int gpu_stall_icnt2sh = 0; -unsigned long long partiton_reqs_in_parallel = 0; -unsigned long long partiton_reqs_in_parallel_total = 0; -unsigned long long partiton_reqs_in_parallel_util = 0; -unsigned long long partiton_reqs_in_parallel_util_total = 0; -unsigned long long gpu_sim_cycle_parition_util = 0; -unsigned long long gpu_tot_sim_cycle_parition_util = 0; -unsigned long long partiton_replys_in_parallel = 0; -unsigned long long partiton_replys_in_parallel_total = 0; - tr1_hash_map<new_addr_type,unsigned> address_random_interleaving; /* Clock Domains */ @@ -113,8 +97,6 @@ tr1_hash_map<new_addr_type,unsigned> address_random_interleaving; #define MEM_LATENCY_STAT_IMPL - - #include "mem_latency_stat.h" void power_config::reg_options(class OptionParser * opp) @@ -520,11 +502,11 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) option_parser_register(opp, "-gpgpu_deadlock_detect", OPT_BOOL, &gpu_deadlock_detect, "Stop the simulation at deadlock (1=on (default), 0=off)", "1"); - option_parser_register(opp, "-gpgpu_ptx_instruction_classification", OPT_INT32, - &gpgpu_ptx_instruction_classification, + option_parser_register(opp, "-gpgpu_ptx_instruction_classification", OPT_INT32, + &(gpgpu_ctx->func_sim->gpgpu_ptx_instruction_classification), "if enabled will classify ptx instruction types per kernel (Max 255 kernels now)", "0"); - option_parser_register(opp, "-gpgpu_ptx_sim_mode", OPT_INT32, &g_ptx_sim_mode, + option_parser_register(opp, "-gpgpu_ptx_sim_mode", OPT_INT32, &(gpgpu_ctx->func_sim->g_ptx_sim_mode), "Select between Performance (default) or Functional simulation (1)", "0"); option_parser_register(opp, "-gpgpu_clock_domains", OPT_CSTR, &gpgpu_clock_domains, @@ -566,16 +548,14 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) option_parser_register(opp, "-trace_sampling_memory_partition", OPT_INT32, &Trace::sampling_memory_partition, "The memory partition which is printed using MEMPART_DPRINTF. Default -1 (i.e. all)", "-1"); - ptx_file_line_stats_options(opp); + gpgpu_ctx->stats->ptx_file_line_stats_options(opp); //Jin: kernel launch latency - extern unsigned g_kernel_launch_latency; option_parser_register(opp, "-gpgpu_kernel_launch_latency", OPT_INT32, - &g_kernel_launch_latency, "Kernel launch latency in cycles. Default: 0", + &(gpgpu_ctx->device_runtime->g_kernel_launch_latency), "Kernel launch latency in cycles. Default: 0", "0"); - extern bool g_cdp_enabled; option_parser_register(opp, "-gpgpu_cdp_enabled", OPT_BOOL, - &g_cdp_enabled, "Turn on CDP", + &(gpgpu_ctx->device_runtime->g_cdp_enabled), "Turn on CDP", "0"); } @@ -719,14 +699,13 @@ void gpgpu_sim::stop_all_running_kernels(){ } } -void set_ptx_warp_size(const struct core_config * warp_size); - -gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) - : gpgpu_t(config), m_config(config) -{ +gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config, gpgpu_context* ctx ) + : gpgpu_t(config, ctx), m_config(config) +{ + gpgpu_ctx = ctx; m_shader_config = &m_config.m_shader_config; m_memory_config = &m_config.m_memory_config; - set_ptx_warp_size(m_shader_config); + ctx->ptx_parser->set_ptx_warp_size(m_shader_config); ptx_file_line_stats_create_exposed_latency_tracker(m_config.num_shader()); #ifdef GPGPUSIM_POWER_MODEL @@ -734,7 +713,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) #endif m_shader_stats = new shader_core_stats(m_shader_config); - m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config); + m_memory_stats = new memory_stats_t(m_config.num_shader(),m_shader_config,m_memory_config,this); average_pipeline_duty_cycle = (float *)malloc(sizeof(float)); active_sms=(float *)malloc(sizeof(float)); m_power_stats = new power_stat_t(m_shader_config,average_pipeline_duty_cycle,active_sms,m_shader_stats,m_memory_config,m_memory_stats); @@ -745,6 +724,16 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) m_total_cta_launched = 0; gpu_deadlock = false; + gpu_stall_dramfull = 0; + gpu_stall_icnt2sh = 0; + partiton_reqs_in_parallel = 0; + partiton_reqs_in_parallel_total = 0; + partiton_reqs_in_parallel_util = 0; + partiton_reqs_in_parallel_util_total = 0; + gpu_sim_cycle_parition_util = 0; + gpu_tot_sim_cycle_parition_util = 0; + partiton_replys_in_parallel = 0; + partiton_replys_in_parallel_total = 0; m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters]; for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) @@ -753,7 +742,7 @@ gpgpu_sim::gpgpu_sim( const gpgpu_sim_config &config ) m_memory_partition_unit = new memory_partition_unit*[m_memory_config->m_n_mem]; m_memory_sub_partition = new memory_sub_partition*[m_memory_config->m_n_mem_sub_partition]; for (unsigned i=0;i<m_memory_config->m_n_mem;i++) { - m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats); + m_memory_partition_unit[i] = new memory_partition_unit(i, m_memory_config, m_memory_stats, this); for (unsigned p = 0; p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) { unsigned submpid = i * m_memory_config->m_n_sub_partition_per_memory_channel + p; m_memory_sub_partition[submpid] = m_memory_partition_unit[i]->get_sub_partition(p); @@ -904,13 +893,13 @@ void gpgpu_sim::init() gpu_sim_cycle_parition_util = 0; reinit_clock_domains(); - set_param_gpgpu_num_shaders(m_config.num_shader()); + gpgpu_ctx->func_sim->set_param_gpgpu_num_shaders(m_config.num_shader()); for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) m_cluster[i]->reinit(); m_shader_stats->new_grid(); // initialize the control-flow, memory access, memory latency logger if (m_config.g_visualizer_enabled) { - create_thread_CFlogger( m_config.num_shader(), m_shader_config->n_thread_per_shader, 0, m_config.gpgpu_cflog_interval ); + create_thread_CFlogger( gpgpu_ctx, m_config.num_shader(), m_shader_config->n_thread_per_shader, 0, m_config.gpgpu_cflog_interval ); } shader_CTA_count_create( m_config.num_shader(), m_config.gpgpu_cflog_interval); if (m_config.gpgpu_cflog_interval != 0) { @@ -956,7 +945,7 @@ void gpgpu_sim::update_stats() { void gpgpu_sim::print_stats() { - ptx_file_line_stats_write_file(); + gpgpu_ctx->stats->ptx_file_line_stats_write_file(); gpu_print_stat(); if (g_network_mode) { @@ -1122,7 +1111,6 @@ void gpgpu_sim::gpu_print_stat() printf("gpu_sim_insn = %lld\n", gpu_sim_insn); printf("gpu_ipc = %12.4f\n", (float)gpu_sim_insn / gpu_sim_cycle); printf("gpu_tot_sim_cycle = %lld\n", gpu_tot_sim_cycle+gpu_sim_cycle); - printf("elapsed_cycles_sm_tot = %lld\n", elapsed_cycles_sm_tot); printf("gpu_tot_sim_insn = %lld\n", gpu_tot_sim_insn+gpu_sim_insn); printf("gpu_tot_ipc = %12.4f\n", (float)(gpu_tot_sim_insn+gpu_sim_insn) / (gpu_tot_sim_cycle+gpu_sim_cycle)); printf("gpu_tot_issued_cta = %lld\n", gpu_tot_issued_cta + m_total_cta_launched); @@ -1130,8 +1118,7 @@ void gpgpu_sim::gpu_print_stat() printf("gpu_tot_occupancy = %.4f\% \n", (gpu_occupancy + gpu_tot_occupancy).get_occ_fraction() * 100); - extern unsigned long long g_max_total_param_size; - fprintf(statfout, "max_total_param_size = %llu\n", g_max_total_param_size); + fprintf(statfout, "max_total_param_size = %llu\n", gpgpu_ctx->device_runtime->g_max_total_param_size); // performance counter for stalls due to congestion. printf("gpu_stall_dramfull = %d\n", gpu_stall_dramfull); @@ -1154,7 +1141,7 @@ void gpgpu_sim::gpu_print_stat() time_t curr_time; time(&curr_time); - unsigned long long elapsed_time = MAX( curr_time - g_simulation_starttime, 1 ); + unsigned long long elapsed_time = MAX( curr_time - GPGPUsim_ctx_ptr()->g_simulation_starttime, 1 ); printf( "gpu_total_sim_rate=%u\n", (unsigned)( ( gpu_tot_sim_insn + gpu_sim_insn ) / elapsed_time ) ); //shader_print_l1_miss_stat( stdout ); @@ -1223,9 +1210,9 @@ void gpgpu_sim::gpu_print_stat() spill_log_to_file (stdout, 1, gpu_sim_cycle); insn_warp_occ_print(stdout); } - if ( gpgpu_ptx_instruction_classification ) { - StatDisp( g_inst_classification_stat[g_ptx_kernel_count]); - StatDisp( g_inst_op_classification_stat[g_ptx_kernel_count]); + if ( gpgpu_ctx->func_sim->gpgpu_ptx_instruction_classification ) { + StatDisp( gpgpu_ctx->func_sim->g_inst_classification_stat[gpgpu_ctx->func_sim->g_ptx_kernel_count]); + StatDisp( gpgpu_ctx->func_sim->g_inst_op_classification_stat[gpgpu_ctx->func_sim->g_ptx_kernel_count]); } #ifdef GPGPUSIM_POWER_MODEL @@ -1518,7 +1505,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) shader_CTA_count_log(m_sid, 1); SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: cta:%2u, start_tid:%4u, end_tid:%4u, initialized @(%lld,%lld)\n", - free_cta_hw_id, start_thread, end_thread, gpu_sim_cycle, gpu_tot_sim_cycle ); + free_cta_hw_id, start_thread, end_thread, m_gpu->gpu_sim_cycle, m_gpu->gpu_tot_sim_cycle ); } @@ -1727,7 +1714,7 @@ void gpgpu_sim::cycle() time_t days, hrs, minutes, sec; time_t curr_time; time(&curr_time); - unsigned long long elapsed_time = MAX(curr_time - g_simulation_starttime, 1); + unsigned long long elapsed_time = MAX(curr_time - GPGPUsim_ctx_ptr()->g_simulation_starttime, 1); if ( (elapsed_time - last_liveness_message_time) >= m_config.liveness_message_freq && DTRACE(LIVENESS) ) { days = elapsed_time/(3600*24); hrs = elapsed_time/3600 - 24*days; @@ -1738,7 +1725,7 @@ void gpgpu_sim::cycle() for (unsigned i=0;i<m_shader_config->n_simt_clusters;i++) { m_cluster[i]->get_current_occupancy(active, total); } - DPRINTF(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s", + DPRINTFG(LIVENESS, "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s", gpu_tot_sim_insn + gpu_sim_insn, (double)gpu_sim_insn/(double)gpu_sim_cycle, float(active)/float(total) * 100, active, total, @@ -1779,7 +1766,7 @@ void gpgpu_sim::cycle() #if (CUDART_VERSION >= 5000) //launch device kernel - launch_one_device_kernel(); + gpgpu_ctx->device_runtime->launch_one_device_kernel(); #endif } } @@ -1852,12 +1839,12 @@ void gpgpu_sim::dump_pipeline( int mask, int s, int m ) const fflush(stdout); } -const struct shader_core_config * gpgpu_sim::getShaderCoreConfig() +const shader_core_config * gpgpu_sim::getShaderCoreConfig() { return m_shader_config; } -const struct memory_config * gpgpu_sim::getMemoryConfig() +const memory_config * gpgpu_sim::getMemoryConfig() { return m_memory_config; } diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index c14d0a7..f841bf9 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -33,6 +33,7 @@ #include "../trace.h" #include "addrdec.h" #include "shader.h" +#include "gpu-cache.h" #include <iostream> #include <fstream> #include <list> @@ -62,8 +63,9 @@ #define SAMPLELOG 222 #define DUMPLOG 333 -extern tr1_hash_map<new_addr_type,unsigned> address_random_interleaving; +class gpgpu_context; +extern tr1_hash_map<new_addr_type,unsigned> address_random_interleaving; enum dram_ctrl_t { DRAM_FIFO=0, @@ -142,13 +144,14 @@ struct power_config { }; - -struct memory_config { - memory_config() +class memory_config { + public: + memory_config(gpgpu_context* ctx) { m_valid = false; gpgpu_dram_timing_opt=NULL; gpgpu_L2_queue_config=NULL; + gpgpu_ctx = ctx; } void init() { @@ -291,17 +294,22 @@ struct memory_config { unsigned write_low_watermark; bool m_perf_sim_memcpy; bool simple_dram_model; + + gpgpu_context* gpgpu_ctx; }; // global counters and flags (please try not to add to this list!!!) extern unsigned long long gpu_sim_cycle; extern unsigned long long gpu_tot_sim_cycle; -extern unsigned long long elapsed_cycles_sm_tot; + extern bool g_interactive_debugger_enabled; class gpgpu_sim_config : public power_config, public gpgpu_functional_sim_config { public: - gpgpu_sim_config() { m_valid = false; } + gpgpu_sim_config(gpgpu_context* ctx): m_shader_config(ctx), m_memory_config(ctx) { + m_valid = false; + gpgpu_ctx = ctx; + } void reg_options(class OptionParser * opp); void init() { @@ -347,6 +355,8 @@ private: void init_clock_domains(void ); + // backward pointer + class gpgpu_context* gpgpu_ctx; bool m_valid; shader_core_config m_shader_config; memory_config m_memory_config; @@ -422,10 +432,31 @@ struct occupancy_stats { } }; +class gpgpu_context; +class ptx_instruction; + +class watchpoint_event { +public: + watchpoint_event() + { + m_thread=NULL; + m_inst=NULL; + } + watchpoint_event(const ptx_thread_info *thd, const ptx_instruction *pI) + { + m_thread=thd; + m_inst = pI; + } + const ptx_thread_info *thread() const { return m_thread; } + const ptx_instruction *inst() const { return m_inst; } +private: + const ptx_thread_info *m_thread; + const ptx_instruction *m_inst; +}; class gpgpu_sim : public gpgpu_t { public: - gpgpu_sim( const gpgpu_sim_config &config ); + gpgpu_sim( const gpgpu_sim_config &config, gpgpu_context* ctx ); void set_prop( struct cudaDeviceProp *prop ); @@ -480,14 +511,14 @@ public: /*! * Returning the configuration of the shader core, used by the functional simulation only so far */ - const struct shader_core_config * getShaderCoreConfig(); + const shader_core_config * getShaderCoreConfig(); //! Get shader core Memory Configuration /*! * Returning the memory configuration of the shader core, used by the functional simulation only so far */ - const struct memory_config * getMemoryConfig(); + const memory_config * getMemoryConfig(); //! Get shader core SIMT cluster @@ -496,6 +527,10 @@ public: */ simt_core_cluster * getSIMTCluster(); + void hit_watchpoint( unsigned watchpoint_num, ptx_thread_info *thd, const ptx_instruction *pI ); + + // backward pointer + class gpgpu_context* gpgpu_ctx; private: // clocks @@ -542,8 +577,8 @@ private: const gpgpu_sim_config &m_config; const struct cudaDeviceProp *m_cuda_properties; - const struct shader_core_config *m_shader_config; - const struct memory_config *m_memory_config; + const shader_core_config *m_shader_config; + const memory_config *m_memory_config; // stats class shader_core_stats *m_shader_stats; @@ -558,6 +593,8 @@ private: std::vector<std::string> m_executed_kernel_names; //< names of kernel for stat printout std::vector<unsigned> m_executed_kernel_uids; //< uids of kernel launches for stat printout + std::map<unsigned,watchpoint_event> g_watchpoint_hits; + 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 @@ -570,6 +607,18 @@ public: occupancy_stats gpu_occupancy; occupancy_stats gpu_tot_occupancy; + // performance counter for stalls due to congestion. + unsigned int gpu_stall_dramfull; + unsigned int gpu_stall_icnt2sh; + unsigned long long partiton_reqs_in_parallel; + unsigned long long partiton_reqs_in_parallel_total; + unsigned long long partiton_reqs_in_parallel_util; + unsigned long long partiton_reqs_in_parallel_util_total; + unsigned long long gpu_sim_cycle_parition_util; + unsigned long long gpu_tot_sim_cycle_parition_util; + unsigned long long partiton_replys_in_parallel; + unsigned long long partiton_replys_in_parallel_total; + FuncCache get_cache_config(std::string kernel_name); void set_cache_config(std::string kernel_name, FuncCache cacheConfig ); diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index f24a596..f1672f9 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -46,32 +46,35 @@ #include "l2cache_trace.h" -mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const +mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const { assert( wr ); - mem_access_t access( type, addr, size, wr ); + mem_access_t access( type, addr, size, wr, m_memory_config->gpgpu_ctx ); mem_fetch *mf = new mem_fetch( access, NULL, WRITE_PACKET_SIZE, -1, -1, -1, - m_memory_config ); + m_memory_config, + cycle); return mf; } memory_partition_unit::memory_partition_unit( unsigned partition_id, - const struct memory_config *config, - class memory_stats_t *stats ) -: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config) + const memory_config *config, + class memory_stats_t *stats, + class gpgpu_sim* gpu) +: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config), m_gpu(gpu) { - m_dram = new dram_t(m_id,m_config,m_stats,this); + m_dram = new dram_t(m_id,m_config,m_stats,this,gpu); m_sub_partition = new memory_sub_partition*[m_config->m_n_sub_partition_per_memory_channel]; for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) { unsigned sub_partition_id = m_id * m_config->m_n_sub_partition_per_memory_channel + p; - m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats); + m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats, gpu); } + } void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_subpart_id, mem_access_sector_mask_t mask ) @@ -80,7 +83,7 @@ void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_s std::string mystring = mask.to_string<char,std::string::traits_type,std::string::allocator_type>(); MEMPART_DPRINTF("Copy Engine Request Received For Address=%llx, local_subpart=%u, global_subpart=%u, sector_mask=%s \n", addr, p, global_subpart_id, mystring.c_str()); - m_sub_partition[p]->force_l2_tag_update(addr,gpu_sim_cycle+gpu_tot_sim_cycle, mask); + m_sub_partition[p]->force_l2_tag_update(addr,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle, mask); } memory_partition_unit::~memory_partition_unit() @@ -92,7 +95,7 @@ memory_partition_unit::~memory_partition_unit() delete[] m_sub_partition; } -memory_partition_unit::arbitration_metadata::arbitration_metadata(const struct memory_config *config) +memory_partition_unit::arbitration_metadata::arbitration_metadata(const memory_config *config) : m_last_borrower(config->m_n_sub_partition_per_memory_channel - 1), m_private_credit(config->m_n_sub_partition_per_memory_channel, 0), m_shared_credit(0) @@ -208,7 +211,7 @@ void memory_partition_unit::simple_dram_model_cycle() // pop completed memory request from dram and push it to dram-to-L2 queue // of the original sub partition - if (!m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle )) { + if (!m_dram_latency_queue.empty() && ( (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle )) { mem_fetch* mf_return = m_dram_latency_queue.front().req; if( mf_return->get_access_type() != L1_WRBK_ACC && mf_return->get_access_type() != L2_WRBK_ACC ) { mf_return->set_reply(); @@ -222,7 +225,7 @@ void memory_partition_unit::simple_dram_model_cycle() delete mf_return; } else { m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return); - mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_arbitration_metadata.return_credit(dest_spid); MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf_return, dest_spid); } @@ -252,7 +255,7 @@ void memory_partition_unit::simple_dram_model_cycle() MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid); dram_delay_t d; d.req = mf; - d.ready_cycle = gpu_sim_cycle+gpu_tot_sim_cycle + m_config->dram_latency; + d.ready_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle + m_config->dram_latency; m_dram_latency_queue.push_back(d); mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); m_arbitration_metadata.borrow_credit(spid); @@ -278,7 +281,7 @@ void memory_partition_unit::dram_cycle() delete mf_return; } else { m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return); - mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_arbitration_metadata.return_credit(dest_spid); MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf_return, dest_spid); } @@ -307,9 +310,9 @@ void memory_partition_unit::dram_cycle() MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid); dram_delay_t d; d.req = mf; - d.ready_cycle = gpu_sim_cycle+gpu_tot_sim_cycle + m_config->dram_latency; + d.ready_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle + m_config->dram_latency; m_dram_latency_queue.push_back(d); - mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_arbitration_metadata.borrow_credit(spid); break; // the DRAM should only accept one request per cycle } @@ -317,11 +320,11 @@ void memory_partition_unit::dram_cycle() //} // DRAM latency queue - if( !m_dram_latency_queue.empty() && ( (gpu_sim_cycle+gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) { - mem_fetch* mf = m_dram_latency_queue.front().req; - m_dram_latency_queue.pop_front(); - m_dram->push(mf); - } + if( !m_dram_latency_queue.empty() && ( (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) { + mem_fetch* mf = m_dram_latency_queue.front().req; + m_dram_latency_queue.pop_front(); + m_dram->push(mf); + } } void memory_partition_unit::set_done( mem_fetch *mf ) @@ -368,12 +371,14 @@ void memory_partition_unit::print( FILE *fp ) const } memory_sub_partition::memory_sub_partition( unsigned sub_partition_id, - const struct memory_config *config, - class memory_stats_t *stats ) + const memory_config *config, + class memory_stats_t *stats, + class gpgpu_sim* gpu) { m_id = sub_partition_id; m_config=config; m_stats=stats; + m_gpu = gpu; m_memcpy_cycle_offset = 0; assert(m_id < m_config->m_n_mem_sub_partition); @@ -384,7 +389,7 @@ memory_sub_partition::memory_sub_partition( unsigned sub_partition_id, m_mf_allocator = new partition_mf_allocator(config); if(!m_config->m_L2_config.disabled()) - m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE); + m_L2cache = new l2_cache(L2c_name,m_config->m_L2_config,-1,-1,m_L2interface,m_mf_allocator,IN_PARTITION_L2_MISS_QUEUE, gpu); unsigned int icnt_L2; unsigned int L2_dram; @@ -416,7 +421,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) mem_fetch *mf = m_L2cache->next_access(); if(mf->get_access_type() != L2_WR_ALLOC_R){ // Don't pass write allocate read request back to upper level cache mf->set_reply(); - mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); }else{ if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE) @@ -424,7 +429,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) mem_fetch* original_wr_mf = mf->get_original_wr_mf(); assert(original_wr_mf); original_wr_mf->set_reply(); - original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_L2_icnt_queue->push(original_wr_mf); } m_request_tracker.erase(mf); @@ -438,13 +443,13 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) mem_fetch *mf = m_dram_L2_queue->top(); if ( !m_config->m_L2_config.disabled() && m_L2cache->waiting_for_fill(mf) ) { if (m_L2cache->fill_port_free()) { - mf->set_status(IN_PARTITION_L2_FILL_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); - m_L2cache->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset); + mf->set_status(IN_PARTITION_L2_FILL_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); + m_L2cache->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset); m_dram_L2_queue->pop(); } } else if ( !m_L2_icnt_queue->full() ) { if(mf->is_write() && mf->get_type() == WRITE_ACK) - mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); m_dram_L2_queue->pop(); } @@ -465,7 +470,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) bool port_free = m_L2cache->data_port_free(); if ( !output_full && port_free ) { std::list<cache_event> events; - enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle+m_memcpy_cycle_offset,events); + enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset,events); bool write_sent = was_write_sent(events); bool read_sent = was_read_sent(events); MEM_SUBPART_DPRINTF("Probing L2 cache Address=%llx, status=%u\n", mf->get_addr(), status); @@ -479,7 +484,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) delete mf; } else { mf->set_reply(); - mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); } m_icnt_L2_queue->pop(); @@ -490,7 +495,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) } else if ( status != RESERVATION_FAIL ) { if(mf->is_write() && (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE || m_config->m_L2_config.m_write_alloc_policy == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) { mf->set_reply(); - mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_L2_icnt_queue->push(mf); } // L2 cache accepted request @@ -503,7 +508,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) } } else { // L2 is disabled or non-texture access to texture-only L2 - mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); m_L2_dram_queue->push(mf); m_icnt_L2_queue->pop(); } @@ -514,7 +519,7 @@ void memory_sub_partition::cache_cycle( unsigned cycle ) mem_fetch* mf = m_rop.front().req; m_rop.pop(); m_icnt_L2_queue->push(mf); - mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); } } @@ -694,7 +699,8 @@ std::vector<mem_fetch*> memory_sub_partition::breakdown_request_to_sector_reques mf->is_write(), mf->get_access_warp_mask(), mf->get_access_byte_mask() & byte_sector_mask, - std::bitset<SECTOR_CHUNCK_SIZE>().set(j)); + std::bitset<SECTOR_CHUNCK_SIZE>().set(j), + m_gpu->gpgpu_ctx); mem_fetch *n_mf = new mem_fetch( *ma, NULL, @@ -703,6 +709,7 @@ std::vector<mem_fetch*> memory_sub_partition::breakdown_request_to_sector_reques mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), + m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle, mf); result.push_back(n_mf); @@ -732,13 +739,13 @@ void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle ) m_request_tracker.insert(req); if( req->istexture() ) { m_icnt_L2_queue->push(req); - req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); } else { rop_delay_t r; r.req = req; r.ready_cycle = cycle + m_config->rop_latency; m_rop.push(r); - req->set_status(IN_PARTITION_ROP_DELAY,gpu_sim_cycle+gpu_tot_sim_cycle); + req->set_status(IN_PARTITION_ROP_DELAY,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); } } } diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 9a51c0e..0f6fe32 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -42,12 +42,12 @@ public: { m_memory_config = config; } - virtual mem_fetch * alloc(const class warp_inst_t &inst, const mem_access_t &access) const + virtual mem_fetch * alloc(const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const { abort(); return NULL; } - virtual mem_fetch * alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr) const; + virtual mem_fetch * alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle) const; private: const memory_config *m_memory_config; }; @@ -58,7 +58,7 @@ private: class memory_partition_unit { public: - memory_partition_unit( unsigned partition_id, const struct memory_config *config, class memory_stats_t *stats ); + memory_partition_unit( unsigned partition_id, const memory_config *config, class memory_stats_t *stats, class gpgpu_sim* gpu ); ~memory_partition_unit(); bool busy() const; @@ -94,10 +94,12 @@ public: unsigned get_mpid() const { return m_id; } + class gpgpu_sim* get_mgpu() const { return m_gpu; } + private: unsigned m_id; - const struct memory_config *m_config; + const memory_config *m_config; class memory_stats_t *m_stats; class memory_sub_partition **m_sub_partition; class dram_t *m_dram; @@ -105,7 +107,7 @@ private: class arbitration_metadata { public: - arbitration_metadata(const struct memory_config *config); + arbitration_metadata(const memory_config *config); // check if a subpartition still has credit bool has_credits(int inner_sub_partition_id) const; @@ -129,7 +131,7 @@ private: std::vector<int> m_private_credit; int m_shared_credit; }; - arbitration_metadata m_arbitration_metadata; + arbitration_metadata m_arbitration_metadata; // determine wheither a given subpartition can issue to DRAM bool can_issue_to_dram(int inner_sub_partition_id); @@ -141,12 +143,14 @@ private: class mem_fetch* req; }; std::list<dram_delay_t> m_dram_latency_queue; + + class gpgpu_sim* m_gpu; }; class memory_sub_partition { public: - memory_sub_partition( unsigned sub_partition_id, const struct memory_config *config, class memory_stats_t *stats ); + memory_sub_partition( unsigned sub_partition_id, const memory_config *config, class memory_stats_t *stats, class gpgpu_sim* gpu ); ~memory_sub_partition(); unsigned get_id() const { return m_id; } @@ -194,9 +198,10 @@ public: private: // data unsigned m_id; //< the global sub partition ID - const struct memory_config *m_config; + const memory_config *m_config; class l2_cache *m_L2cache; class L2interface *m_L2interface; + class gpgpu_sim* m_gpu; partition_mf_allocator *m_mf_allocator; // model delay of ROP units with a fixed latency diff --git a/src/gpgpu-sim/l2cache_trace.h b/src/gpgpu-sim/l2cache_trace.h index 2235cdc..d2dd948 100644 --- a/src/gpgpu-sim/l2cache_trace.h +++ b/src/gpgpu-sim/l2cache_trace.h @@ -42,7 +42,7 @@ #define MEMPART_DPRINTF(...) do {\ if (MEMPART_DTRACE(MEMORY_PARTITION_UNIT)) {\ printf( MEMPART_PRINT_STR,\ - gpu_sim_cycle + gpu_tot_sim_cycle,\ + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\ Trace::trace_streams_str[Trace::MEMORY_PARTITION_UNIT],\ get_mpid() );\ printf(__VA_ARGS__);\ @@ -52,7 +52,7 @@ #define MEM_SUBPART_DPRINTF(...) do {\ if (MEM_SUBPART_DTRACE(MEMORY_PARTITION_UNIT)) {\ printf( MEM_SUBPART_PRINT_STR,\ - gpu_sim_cycle + gpu_tot_sim_cycle,\ + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\ Trace::trace_streams_str[Trace::MEMORY_SUBPARTITION_UNIT],\ m_id );\ printf(__VA_ARGS__);\ diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc index a260a35..6a00889 100644 --- a/src/gpgpu-sim/mem_fetch.cc +++ b/src/gpgpu-sim/mem_fetch.cc @@ -39,9 +39,10 @@ mem_fetch::mem_fetch( const mem_access_t &access, unsigned wid, unsigned sid, unsigned tpc, - const struct memory_config *config, + const memory_config *config, + unsigned long long cycle, mem_fetch *m_original_mf, - mem_fetch *m_original_wr_mf) + mem_fetch *m_original_wr_mf):m_access(access) { m_request_uid = sm_next_mf_request_uid++; @@ -58,10 +59,10 @@ mem_fetch::mem_fetch( const mem_access_t &access, config->m_address_mapping.addrdec_tlx(access.get_addr(),&m_raw_addr); m_partition_addr = config->m_address_mapping.partition_address(access.get_addr()); m_type = m_access.is_write()?WRITE_REQUEST:READ_REQUEST; - m_timestamp = gpu_sim_cycle + gpu_tot_sim_cycle; + m_timestamp = cycle; m_timestamp2 = 0; m_status = MEM_FETCH_INITIALIZED; - m_status_change = gpu_sim_cycle + gpu_tot_sim_cycle; + m_status_change = cycle; m_mem_config = config; icnt_flit_size = config->icnt_flit_size; original_mf = m_original_mf; diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h index e5efffd..1cab9f2 100644 --- a/src/gpgpu-sim/mem_fetch.h +++ b/src/gpgpu-sim/mem_fetch.h @@ -47,6 +47,7 @@ enum mf_type { #undef MF_TUP #undef MF_TUP_END +class memory_config; class mem_fetch { public: mem_fetch( const mem_access_t &access, @@ -55,7 +56,8 @@ public: unsigned wid, unsigned sid, unsigned tpc, - const struct memory_config *config, + const memory_config *config, + unsigned long long cycle, mem_fetch *original_mf = NULL, mem_fetch *original_wr_mf = NULL); ~mem_fetch(); @@ -148,7 +150,7 @@ private: static unsigned sm_next_mf_request_uid; - const struct memory_config *m_mem_config; + const memory_config *m_mem_config; unsigned icnt_flit_size; mem_fetch* original_mf; //this pointer is set up when a request is divided into sector requests at L2 cache (if the req size > L2 sector size), so the pointer refers to the original request diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index 11624f4..a1b43a8 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -41,8 +41,9 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> +#include "../../libcuda/gpgpu_context.h" -memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_config *shader_config, const struct memory_config *mem_config ) +memory_stats_t::memory_stats_t( unsigned n_shader, const shader_core_config *shader_config, const memory_config *mem_config, const class gpgpu_sim* gpu ) { assert( mem_config->m_valid ); assert( shader_config->m_valid ); @@ -67,6 +68,7 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf m_n_shader=n_shader; m_memory_config=mem_config; + m_gpu=gpu; total_n_access=0; total_n_reads=0; total_n_writes=0; @@ -147,7 +149,7 @@ memory_stats_t::memory_stats_t( unsigned n_shader, const struct shader_core_conf unsigned memory_stats_t::memlatstat_done(mem_fetch *mf ) { unsigned mf_latency; - mf_latency = (gpu_sim_cycle+gpu_tot_sim_cycle) - mf->get_timestamp(); + mf_latency = (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) - mf->get_timestamp(); mf_num_lat_pw++; mf_tot_lat_pw += mf_latency; unsigned idx = LOGB2(mf_latency); @@ -167,7 +169,7 @@ void memory_stats_t::memlatstat_read_done(mem_fetch *mf) if (mf_latency > mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk]) mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk] = mf_latency; unsigned icnt2sh_latency; - icnt2sh_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_return_timestamp(); + icnt2sh_latency = (m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle) - mf->get_return_timestamp(); tot_icnt2sh_latency += icnt2sh_latency; icnt2sh_lat_table[LOGB2(icnt2sh_latency)]++; if (icnt2sh_latency > max_icnt2sh_latency) @@ -194,14 +196,14 @@ void memory_stats_t::memlatstat_dram_access(mem_fetch *mf) mem_access_type_stats[mf->get_access_type()][dram_id][bank]++; } if (mf->get_pc() != (unsigned)-1) - ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size()); + m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size()); } void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf) { if (m_memory_config->gpgpu_memlatency_stat) { unsigned icnt2mem_latency; - icnt2mem_latency = (gpu_tot_sim_cycle+gpu_sim_cycle) - mf->get_timestamp(); + icnt2mem_latency = (m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle) - mf->get_timestamp(); tot_icnt2mem_latency += icnt2mem_latency; icnt2mem_lat_table[LOGB2(icnt2mem_latency)]++; if (icnt2mem_latency > max_icnt2mem_latency) diff --git a/src/gpgpu-sim/mem_latency_stat.h b/src/gpgpu-sim/mem_latency_stat.h index 982b9ae..0c84972 100644 --- a/src/gpgpu-sim/mem_latency_stat.h +++ b/src/gpgpu-sim/mem_latency_stat.h @@ -32,11 +32,13 @@ #include <zlib.h> #include <map> +class memory_config; class memory_stats_t { public: memory_stats_t( unsigned n_shader, - const struct shader_core_config *shader_config, - const struct memory_config *mem_config ); + const class shader_core_config *shader_config, + const memory_config *mem_config, + const class gpgpu_sim* gpu); unsigned memlatstat_done( class mem_fetch *mf ); void memlatstat_read_done( class mem_fetch *mf ); @@ -52,8 +54,9 @@ public: unsigned m_n_shader; - const struct shader_core_config *m_shader_config; - const struct memory_config *m_memory_config; + const shader_core_config *m_shader_config; + const memory_config *m_memory_config; + const class gpgpu_sim* m_gpu; unsigned max_mrq_latency; unsigned max_dq_latency; diff --git a/src/gpgpu-sim/power_interface.cc b/src/gpgpu-sim/power_interface.cc index 3861b6a..0272aa6 100644 --- a/src/gpgpu-sim/power_interface.cc +++ b/src/gpgpu-sim/power_interface.cc @@ -38,7 +38,7 @@ void init_mcpat(const gpgpu_sim_config &config, class gpgpu_sim_wrapper *wrapper } -void mcpat_cycle(const gpgpu_sim_config &config, const struct shader_core_config *shdr_config, class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, unsigned tot_inst, unsigned inst){ +void mcpat_cycle(const gpgpu_sim_config &config, const shader_core_config *shdr_config, class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, unsigned tot_inst, unsigned inst){ static bool mcpat_init=true; diff --git a/src/gpgpu-sim/power_interface.h b/src/gpgpu-sim/power_interface.h index afac22b..a388c23 100644 --- a/src/gpgpu-sim/power_interface.h +++ b/src/gpgpu-sim/power_interface.h @@ -36,7 +36,7 @@ #include "gpgpu_sim_wrapper.h" void init_mcpat(const gpgpu_sim_config &config, class gpgpu_sim_wrapper *wrapper, unsigned stat_sample_freq, unsigned tot_inst, unsigned inst); -void mcpat_cycle(const gpgpu_sim_config &config, const struct shader_core_config *shdr_config, class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, +void mcpat_cycle(const gpgpu_sim_config &config, const shader_core_config *shdr_config, class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, unsigned tot_inst, unsigned inst); void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper); diff --git a/src/gpgpu-sim/power_stat.cc b/src/gpgpu-sim/power_stat.cc index 4c995e9..2c02082 100644 --- a/src/gpgpu-sim/power_stat.cc +++ b/src/gpgpu-sim/power_stat.cc @@ -42,7 +42,7 @@ -power_mem_stat_t::power_mem_stat_t(const struct memory_config *mem_config, const struct shader_core_config *shdr_config, memory_stats_t *mem_stats, shader_core_stats *shdr_stats){ +power_mem_stat_t::power_mem_stat_t(const memory_config *mem_config, const shader_core_config *shdr_config, memory_stats_t *mem_stats, shader_core_stats *shdr_stats){ assert( mem_config->m_valid ); m_mem_stats = mem_stats; m_config = mem_config; @@ -125,7 +125,7 @@ void power_mem_stat_t::print (FILE *fout) const { } -power_core_stat_t::power_core_stat_t( const struct shader_core_config *shader_config, shader_core_stats *core_stats ) +power_core_stat_t::power_core_stat_t( const shader_core_config *shader_config, shader_core_stats *core_stats ) { assert( shader_config->m_valid ); m_config = shader_config; @@ -266,7 +266,7 @@ for(unsigned i=0; i<m_config->num_shader(); ++i){ } } -power_stat_t::power_stat_t( const struct shader_core_config *shader_config,float * average_pipeline_duty_cycle,float *active_sms,shader_core_stats * shader_stats, const struct memory_config *mem_config,memory_stats_t * memory_stats) +power_stat_t::power_stat_t( const shader_core_config *shader_config,float * average_pipeline_duty_cycle,float *active_sms,shader_core_stats * shader_stats, const memory_config *mem_config,memory_stats_t * memory_stats) { assert( shader_config->m_valid ); assert( mem_config->m_valid ); diff --git a/src/gpgpu-sim/power_stat.h b/src/gpgpu-sim/power_stat.h index 20af2e5..24ade99 100644 --- a/src/gpgpu-sim/power_stat.h +++ b/src/gpgpu-sim/power_stat.h @@ -73,7 +73,7 @@ struct shader_core_power_stats_pod { class power_core_stat_t : public shader_core_power_stats_pod { public: - power_core_stat_t(const struct shader_core_config *shader_config, shader_core_stats *core_stats); + power_core_stat_t(const shader_core_config *shader_config, shader_core_stats *core_stats); void visualizer_print( gzFile visualizer_file ); void print (FILE *fout); void init(); @@ -113,7 +113,7 @@ struct mem_power_stats_pod{ class power_mem_stat_t : public mem_power_stats_pod{ public: - power_mem_stat_t(const struct memory_config *mem_config, const struct shader_core_config *shdr_config, memory_stats_t *mem_stats, shader_core_stats *shdr_stats); + power_mem_stat_t(const memory_config *mem_config, const shader_core_config *shdr_config, memory_stats_t *mem_stats, shader_core_stats *shdr_stats); void visualizer_print( gzFile visualizer_file ); void print (FILE *fout) const; void init(); @@ -128,7 +128,7 @@ private: class power_stat_t { public: - power_stat_t( const struct shader_core_config *shader_config,float * average_pipeline_duty_cycle,float * active_sms,shader_core_stats * shader_stats, const struct memory_config *mem_config,memory_stats_t * memory_stats); + power_stat_t( const shader_core_config *shader_config,float * average_pipeline_duty_cycle,float * active_sms,shader_core_stats * shader_stats, const memory_config *mem_config,memory_stats_t * memory_stats); void visualizer_print( gzFile visualizer_file ); void print (FILE *fout) const; void save_stats(){ @@ -621,7 +621,7 @@ public: float * m_average_pipeline_duty_cycle; float * m_active_sms; const shader_core_config *m_config; - const struct memory_config *m_mem_config; + const memory_config *m_mem_config; }; diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc index ebec891..80f95c6 100644 --- a/src/gpgpu-sim/scoreboard.cc +++ b/src/gpgpu-sim/scoreboard.cc @@ -32,13 +32,15 @@ //Constructor -Scoreboard::Scoreboard( unsigned sid, unsigned n_warps ) +Scoreboard::Scoreboard( unsigned sid, unsigned n_warps, class gpgpu_t* gpu ) : longopregs() { m_sid = sid; //Initialize size of table reg_table.resize(n_warps); longopregs.resize(n_warps); + + m_gpu = gpu; } // Print scoreboard contents diff --git a/src/gpgpu-sim/scoreboard.h b/src/gpgpu-sim/scoreboard.h index 4a76ea3..a4baa19 100644 --- a/src/gpgpu-sim/scoreboard.h +++ b/src/gpgpu-sim/scoreboard.h @@ -38,7 +38,7 @@ class Scoreboard { public: - Scoreboard( unsigned sid, unsigned n_warps ); + Scoreboard( unsigned sid, unsigned n_warps, class gpgpu_t* gpu ); void reserveRegisters(const warp_inst_t *inst); void releaseRegisters(const warp_inst_t *inst); @@ -59,6 +59,8 @@ private: std::vector< std::set<unsigned> > reg_table; //Register that depend on a long operation (global, local or tex memory) std::vector< std::set<unsigned> > longopregs; + + class gpgpu_t* m_gpu; }; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index e38eefd..c697450 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -28,7 +28,6 @@ #include <float.h> #include "shader.h" -#include "gpu-sim.h" #include "addrdec.h" #include "dram.h" #include "stat-tool.h" @@ -46,12 +45,26 @@ #include <limits.h> #include "traffic_breakdown.h" #include "shader_trace.h" +#include "../../libcuda/gpgpu_context.h" #define PRIORITIZE_MSHR_OVER_WB 1 #define MAX(a,b) (((a)>(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b)) +mem_fetch *shader_core_mem_fetch_allocator::alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const +{ + mem_access_t access( type, addr, size, wr, m_memory_config->gpgpu_ctx); + mem_fetch *mf = new mem_fetch( access, + NULL, + wr?WRITE_PACKET_SIZE:READ_PACKET_SIZE, + -1, + m_core_id, + m_cluster_id, + m_memory_config, + cycle); + return mf; +} ///////////////////////////////////////////////////////////////////////////// std::list<unsigned> shader_core_ctx::get_regs_written( const inst_t &fvt ) const @@ -69,8 +82,8 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, class simt_core_cluster *cluster, unsigned shader_id, unsigned tpc_id, - const struct shader_core_config *config, - const struct memory_config *mem_config, + const shader_core_config *config, + const memory_config *mem_config, shader_core_stats *stats ) : core_t( gpu, NULL, config->warp_size, config->n_thread_per_shader ), m_barriers( this, config->max_warps_per_shader, config->max_cta_per_core, config->max_barriers_per_cta, config->warp_size ), @@ -133,7 +146,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_L1I = new read_only_cache( name,m_config->m_L1I_config,m_sid,get_shader_instruction_cache_id(),m_icnt,IN_L1I_MISS_QUEUE); m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size)); - m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader); + m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, gpu); //scedulers //must currently occur after all inputs have been initialized. @@ -731,7 +744,7 @@ void shader_core_ctx::decode() if( m_inst_fetch_buffer.m_valid ) { // decode 1 or 2 instructions and place them into ibuffer address_type pc = m_inst_fetch_buffer.m_pc; - const warp_inst_t* pI1 = ptx_fetch_inst(pc); + const warp_inst_t* pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0,pI1); m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); if( pI1 ) { @@ -741,7 +754,7 @@ void shader_core_ctx::decode() }else if(pI1->oprnd_type==FP_OP) { m_stats->m_num_FPdecoded_insn[m_sid]++; } - const warp_inst_t* pI2 = ptx_fetch_inst(pc+pI1->isize); + const warp_inst_t* pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc+pI1->isize); if( pI2 ) { m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2); m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); @@ -767,7 +780,7 @@ void shader_core_ctx::fetch() m_inst_fetch_buffer = ifetch_buffer_t(m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid()); assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting. m_inst_fetch_buffer.m_valid = true; - m_warp[mf->get_wid()].set_last_fetch(gpu_sim_cycle); + m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; } else { @@ -808,24 +821,26 @@ void shader_core_ctx::fetch() // TODO: replace with use of allocator // mem_fetch *mf = m_mem_fetch_allocator->alloc() - mem_access_t acc(INST_ACC_R,ppc,nbytes,false); + mem_access_t acc(INST_ACC_R,ppc,nbytes,false, m_gpu->gpgpu_ctx); mem_fetch *mf = new mem_fetch(acc, NULL/*we don't have an instruction yet*/, READ_PACKET_SIZE, warp_id, m_sid, m_tpc, - m_memory_config ); + m_memory_config, + m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle + ); std::list<cache_event> events; - enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, gpu_sim_cycle+gpu_tot_sim_cycle,events); + enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle,events); if( status == MISS ) { m_last_warp_fetched=warp_id; m_warp[warp_id].set_imiss_pending(); - m_warp[warp_id].set_last_fetch(gpu_sim_cycle); + m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle); } else if( status == HIT ) { m_last_warp_fetched=warp_id; m_inst_fetch_buffer = ifetch_buffer_t(pc,nbytes,warp_id); - m_warp[warp_id].set_last_fetch(gpu_sim_cycle); + m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; } else { m_last_warp_fetched=warp_id; @@ -859,7 +874,7 @@ void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* m_warp[warp_id].ibuffer_free(); assert(next_inst->valid()); **pipe_reg = *next_inst; // static instruction information - (*pipe_reg)->issue( active_mask, warp_id, gpu_tot_sim_cycle + gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information + (*pipe_reg)->issue( active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; func_exec_inst( **pipe_reg ); if( next_inst->op == BARRIER_OP ){ @@ -1022,7 +1037,7 @@ void scheduler_unit::cycle() m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc,&rpc); SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) has valid instruction (%s)\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id(), - ptx_get_insn_str( pc).c_str() ); + m_shader->m_config->gpgpu_ctx->func_sim->ptx_get_insn_str( pc).c_str() ); if( pI ) { assert(valid); if( pc != pI->pc ) { @@ -1081,12 +1096,11 @@ void scheduler_unit::cycle() if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) { assert(warp(warp_id).m_cdp_latency == 0); - extern unsigned cdp_latency[5]; if(pI->m_is_cdp == 1) - warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1]; + warp(warp_id).m_cdp_latency = m_shader->m_config->gpgpu_ctx->func_sim->cdp_latency[pI->m_is_cdp - 1]; else //cudaLaunchDeviceV2 and cudaGetParameterBufferV2 - warp(warp_id).m_cdp_latency = cdp_latency[pI->m_is_cdp - 1] - + cdp_latency[pI->m_is_cdp] * active_mask.count(); + warp(warp_id).m_cdp_latency = m_shader->m_config->gpgpu_ctx->func_sim->cdp_latency[pI->m_is_cdp - 1] + + m_shader->m_config->gpgpu_ctx->func_sim->cdp_latency[pI->m_is_cdp] * active_mask.count(); warp(warp_id).m_cdp_dummy = true; break; } @@ -1514,7 +1528,7 @@ void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst) m_stats->m_num_sim_winsn[m_sid]++; m_gpu->gpu_sim_insn += inst.active_count(); - inst.completed(gpu_tot_sim_cycle + gpu_sim_cycle); + inst.completed(m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); } void shader_core_ctx::writeback() @@ -1552,9 +1566,9 @@ void shader_core_ctx::writeback() m_warp[warp_id].dec_inst_in_pipeline(); warp_inst_complete(*pipe_reg); m_gpu->gpu_sim_insn_last_update_sid = m_sid; - m_gpu->gpu_sim_insn_last_update = gpu_sim_cycle; - m_last_inst_gpu_sim_cycle = gpu_sim_cycle; - m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle; + m_gpu->gpu_sim_insn_last_update = m_gpu->gpu_sim_cycle; + m_last_inst_gpu_sim_cycle = m_gpu->gpu_sim_cycle; + m_last_inst_gpu_tot_sim_cycle = m_gpu->gpu_tot_sim_cycle; pipe_reg->clear(); preg = m_pipeline_reg[EX_WB].get_ready(); pipe_reg = (preg==NULL)? NULL:*preg; @@ -1633,9 +1647,9 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue( cache_t *cache, war return DATA_PORT_STALL; //const mem_access_t &access = inst.accessq_back(); - mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back()); + mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back(),m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); std::list<cache_event> events; - enum cache_request_status status = cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events); + enum cache_request_status status = cache->access(mf->get_addr(),mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events); return process_cache_access( cache, mf->get_addr(), inst, events, mf, status ); } @@ -1645,7 +1659,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( l1_cache *c if( inst.accessq_empty() ) return result; - mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back()); + mem_fetch *mf = m_mf_allocator->alloc(inst,inst.accessq_back(),m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); if(m_config->m_L1D_config.l1_latency > 0) { @@ -1675,7 +1689,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( l1_cache *c else { std::list<cache_event> events; - enum cache_request_status status = cache->access(mf->get_addr(),mf,gpu_sim_cycle+gpu_tot_sim_cycle,events); + enum cache_request_status status = cache->access(mf->get_addr(),mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events); return process_cache_access( cache, mf->get_addr(), inst, events, mf, status ); } } @@ -1687,7 +1701,7 @@ void ldst_unit::L1_latency_queue_cycle() { mem_fetch* mf_next = l1_latency_queue[0]; std::list<cache_event> events; - enum cache_request_status status = m_L1D->access(mf_next->get_addr(),mf_next,gpu_sim_cycle+gpu_tot_sim_cycle,events); + enum cache_request_status status = m_L1D->access(mf_next->get_addr(),mf_next,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle,events); bool write_sent = was_write_sent(events); bool read_sent = was_read_sent(events); @@ -1804,7 +1818,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea if( m_icnt->full(size, inst.is_store() || inst.isatomic()) ) { stall_cond = ICNT_RC_FAIL; } else { - mem_fetch *mf = m_mf_allocator->alloc(inst,access); + mem_fetch *mf = m_mf_allocator->alloc(inst,access,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); m_icnt->push(mf); inst.accessq_pop_back(); //inst.clear_active( access.get_warp_mask() ); @@ -1840,7 +1854,7 @@ bool ldst_unit::response_buffer_full() const void ldst_unit::fill( mem_fetch *mf ) { - mf->set_status(IN_SHADER_LDST_RESPONSE_FIFO,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_SHADER_LDST_RESPONSE_FIFO,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); m_response_fifo.push_back(mf); } @@ -2115,7 +2129,8 @@ ldst_unit::ldst_unit( mem_fetch_interface *icnt, get_shader_normal_cache_id(), m_icnt, m_mf_allocator, - IN_L1D_MISS_QUEUE ); + IN_L1D_MISS_QUEUE, + core->get_gpu()); if(m_config->m_L1D_config.l1_latency > 0) { @@ -2202,8 +2217,8 @@ void ldst_unit::writeback() m_core->warp_inst_complete(m_next_wb); } m_next_wb.clear(); - m_last_inst_gpu_sim_cycle = gpu_sim_cycle; - m_last_inst_gpu_tot_sim_cycle = gpu_tot_sim_cycle; + m_last_inst_gpu_sim_cycle = m_core->get_gpu()->gpu_sim_cycle; + m_last_inst_gpu_tot_sim_cycle = m_core->get_gpu()->gpu_tot_sim_cycle; } } @@ -2311,13 +2326,13 @@ void ldst_unit::cycle() mem_fetch *mf = m_response_fifo.front(); if (mf->get_access_type() == TEXTURE_ACC_R) { if (m_L1T->fill_port_free()) { - m_L1T->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L1T->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); m_response_fifo.pop_front(); } } else if (mf->get_access_type() == CONST_ACC_R) { if (m_L1C->fill_port_free()) { - mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle); - m_L1C->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_SHADER_FETCHED,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); + m_L1C->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); m_response_fifo.pop_front(); } } else { @@ -2337,13 +2352,13 @@ void ldst_unit::cycle() } if( bypassL1D ) { if ( m_next_global == NULL ) { - mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_SHADER_FETCHED,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); m_response_fifo.pop_front(); m_next_global = mf; } } else { if (m_L1D->fill_port_free()) { - m_L1D->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle); + m_L1D->fill(mf,m_core->get_gpu()->gpu_sim_cycle+m_core->get_gpu()->gpu_tot_sim_cycle); m_response_fifo.pop_front(); } } @@ -2432,7 +2447,7 @@ void shader_core_ctx::register_cta_thread_exit( unsigned cta_num, kernel_info_t shader_CTA_count_unlog(m_sid, 1); SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Finished CTA #%d (%lld,%lld), %u CTAs running\n", - cta_num, gpu_sim_cycle, gpu_tot_sim_cycle, m_n_active_cta); + cta_num, m_gpu->gpu_sim_cycle, m_gpu->gpu_tot_sim_cycle, m_n_active_cta); if( m_n_active_cta == 0 ) { SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Empty (last released kernel %u \'%s\').\n", @@ -2686,7 +2701,7 @@ void warp_inst_t::print( FILE *fout ) const for (unsigned j=0; j<m_config->warp_size; j++) fprintf(fout, "%c", (active(j)?'1':'0') ); fprintf(fout, "]: "); - ptx_print_insn( pc, fout ); + m_config->gpgpu_ctx->func_sim->ptx_print_insn( pc, fout ); fprintf(fout, "\n"); } void shader_core_ctx::incexecstat(warp_inst_t *&inst) @@ -2823,7 +2838,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, int mask ) con { fprintf(fout, "=================================================\n"); fprintf(fout, "shader %u at cycle %Lu+%Lu (%u threads running)\n", m_sid, - gpu_tot_sim_cycle, gpu_sim_cycle, m_not_completed); + m_gpu->gpu_tot_sim_cycle, m_gpu->gpu_sim_cycle, m_not_completed); fprintf(fout, "=================================================\n"); dump_warp_state(fout); @@ -3015,18 +3030,18 @@ void shader_core_config::set_pipeline_latency() { * [3] MAD * [4] DIV */ - sscanf(opcode_latency_int, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_int, "%u,%u,%u,%u,%u", &int_latency[0],&int_latency[1],&int_latency[2], &int_latency[3],&int_latency[4]); - sscanf(opcode_latency_fp, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_fp, "%u,%u,%u,%u,%u", &fp_latency[0],&fp_latency[1],&fp_latency[2], &fp_latency[3],&fp_latency[4]); - sscanf(opcode_latency_dp, "%u,%u,%u,%u,%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_dp, "%u,%u,%u,%u,%u", &dp_latency[0],&dp_latency[1],&dp_latency[2], &dp_latency[3],&dp_latency[4]); - sscanf(opcode_latency_sfu, "%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_sfu, "%u", &sfu_latency); - sscanf(opcode_latency_tensor, "%u", + sscanf(gpgpu_ctx->func_sim->opcode_latency_tensor, "%u", &tensor_latency); //all div operation are executed on sfu @@ -3045,7 +3060,6 @@ void shader_core_ctx::cycle() if(!isactive() && get_not_completed() == 0) return; - elapsed_cycles_sm_tot++; m_stats->shader_cycles[m_sid]++; writeback(); execute(); @@ -3222,7 +3236,7 @@ void barrier_set_t::warp_reaches_barrier(unsigned cta_id,unsigned warp_id,warp_i cta_to_warp_t::iterator w=m_cta_to_warps.find(cta_id); if( w == m_cta_to_warps.end() ) { // cta is active - printf("ERROR ** cta_id %u not found in barrier set on cycle %llu+%llu...\n", cta_id, gpu_tot_sim_cycle, gpu_sim_cycle ); + printf("ERROR ** cta_id %u not found in barrier set on cycle %llu+%llu...\n", cta_id, m_shader->get_gpu()->gpu_tot_sim_cycle, m_shader->get_gpu()->gpu_sim_cycle ); dump(); abort(); } @@ -3395,8 +3409,8 @@ bool shader_core_ctx::fetch_unit_response_buffer_full() const void shader_core_ctx::accept_fetch_response( mem_fetch *mf ) { - mf->set_status(IN_SHADER_FETCHED,gpu_sim_cycle+gpu_tot_sim_cycle); - m_L1I->fill(mf,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_SHADER_FETCHED,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); + m_L1I->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); } bool shader_core_ctx::ldst_unit_response_buffer_full() const @@ -3784,8 +3798,8 @@ void opndcoll_rfu_t::collector_unit_t::dispatch() simt_core_cluster::simt_core_cluster( class gpgpu_sim *gpu, unsigned cluster_id, - const struct shader_core_config *config, - const struct memory_config *mem_config, + const shader_core_config *config, + const memory_config *mem_config, shader_core_stats *stats, class memory_stats_t *mstats ) { @@ -3958,7 +3972,7 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) } m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size); unsigned destination = mf->get_sub_partition_id(); - mf->set_status(IN_ICNT_TO_MEM,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_ICNT_TO_MEM,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); if (!mf->get_is_write() && !mf->isatomic()) ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void*)mf, mf->get_ctrl_size() ); else @@ -3997,7 +4011,7 @@ void simt_core_cluster::icnt_cycle() // - For write-ack, the packet only has control metadata unsigned int packet_size = (mf->get_is_write())? mf->get_ctrl_size() : mf->size(); m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size); - mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,gpu_sim_cycle+gpu_tot_sim_cycle); + mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle); //m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader); m_response_fifo.push_back(mf); m_stats->n_mem_to_simt[m_cluster_id] += mf->get_num_flits(false); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index a0c2b63..b0d7f7f 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -69,6 +69,8 @@ #define WRITE_MASK_SIZE 8 +class gpgpu_context; + enum exec_unit_type_t { NONE = 0, @@ -116,7 +118,6 @@ public: m_done_exit=true; m_last_fetch=0; m_next=0; - m_inst_at_barrier=NULL; //Jin: cdp support m_cdp_latency = 0; @@ -173,8 +174,8 @@ public: address_type get_pc() const { return m_next_pc; } void set_next_pc( address_type pc ) { m_next_pc = pc; } - void store_info_of_last_inst_at_barrier(const warp_inst_t *pI){ m_inst_at_barrier = pI;} - const warp_inst_t * restore_info_of_last_inst_at_barrier(){ return m_inst_at_barrier;} + void store_info_of_last_inst_at_barrier(const warp_inst_t *pI){ m_inst_at_barrier = *pI;} + warp_inst_t * restore_info_of_last_inst_at_barrier(){ return &m_inst_at_barrier;} void ibuffer_fill( unsigned slot, const warp_inst_t *pI ) { @@ -264,7 +265,7 @@ private: bool m_valid; }; - const warp_inst_t *m_inst_at_barrier; + warp_inst_t m_inst_at_barrier; ibuffer_entry m_ibuffer[IBUFFER_SIZE]; unsigned m_next; @@ -295,7 +296,7 @@ typedef std::bitset<WARP_PER_CTA_MAX> warp_set_t; int register_bank(int regnum, int wid, unsigned num_banks, unsigned bank_warp_shift, bool sub_core_model, unsigned banks_per_sched, unsigned sched_id ); class shader_core_ctx; -struct shader_core_config; +class shader_core_config; class shader_core_stats; enum scheduler_prioritization_type @@ -1033,7 +1034,7 @@ struct ifetch_buffer_t { unsigned m_warp_id; }; -struct shader_core_config; +class shader_core_config; class simd_function_unit { public: @@ -1363,10 +1364,12 @@ const char* const pipeline_stage_name_decode[] = { "N_PIPELINE_STAGES" }; -struct shader_core_config : public core_config +class shader_core_config : public core_config { - shader_core_config(){ + public: + shader_core_config(gpgpu_context* ctx):core_config(ctx){ pipeline_widths_string = NULL; + gpgpu_ctx = ctx; } void init() @@ -1426,6 +1429,8 @@ struct shader_core_config : public core_config unsigned cid_to_sid( unsigned cid, unsigned cluster_id ) const { return cluster_id*n_simt_cores_per_cluster + cid; } void set_pipeline_latency(); + // backward pointer + class gpgpu_context* gpgpu_ctx; // data char *gpgpu_shader_core_pipeline_opt; bool gpgpu_perfect_mem; @@ -1722,6 +1727,7 @@ private: friend class LooseRoundRobbinScheduler; }; +class memory_config; class shader_core_mem_fetch_allocator : public mem_fetch_allocator { public: shader_core_mem_fetch_allocator( unsigned core_id, unsigned cluster_id, const memory_config *config ) @@ -1730,20 +1736,8 @@ public: m_cluster_id = cluster_id; m_memory_config = config; } - mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr ) const - { - mem_access_t access( type, addr, size, wr ); - mem_fetch *mf = new mem_fetch( access, - NULL, - wr?WRITE_PACKET_SIZE:READ_PACKET_SIZE, - -1, - m_core_id, - m_cluster_id, - m_memory_config ); - return mf; - } - - mem_fetch *alloc( const warp_inst_t &inst, const mem_access_t &access ) const + mem_fetch *alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) const; + mem_fetch *alloc( const warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle ) const { warp_inst_t inst_copy = inst; mem_fetch *mf = new mem_fetch(access, @@ -1752,7 +1746,8 @@ public: inst.warp_id(), m_core_id, m_cluster_id, - m_memory_config); + m_memory_config, + cycle); return mf; } @@ -1769,8 +1764,8 @@ public: class simt_core_cluster *cluster, unsigned shader_id, unsigned tpc_id, - const struct shader_core_config *config, - const struct memory_config *mem_config, + const shader_core_config *config, + const memory_config *mem_config, shader_core_stats *stats ); // used by simt_core_cluster: @@ -2064,8 +2059,8 @@ class simt_core_cluster { public: simt_core_cluster( class gpgpu_sim *gpu, unsigned cluster_id, - const struct shader_core_config *config, - const struct memory_config *mem_config, + const shader_core_config *config, + const memory_config *mem_config, shader_core_stats *stats, memory_stats_t *mstats ); diff --git a/src/gpgpu-sim/shader_trace.h b/src/gpgpu-sim/shader_trace.h index de3e059..ac4e894 100644 --- a/src/gpgpu-sim/shader_trace.h +++ b/src/gpgpu-sim/shader_trace.h @@ -44,7 +44,7 @@ #define SHADER_DPRINTF(x, ...) do {\ if (SHADER_DTRACE(x)) {\ printf( SHADER_PRINT_STR,\ - gpu_sim_cycle + gpu_tot_sim_cycle,\ + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\ Trace::trace_streams_str[Trace::x],\ get_sid() );\ printf(__VA_ARGS__);\ @@ -56,7 +56,7 @@ #define SCHED_DPRINTF(...) do {\ if (SHADER_DTRACE(WARP_SCHEDULER)) {\ printf( SCHED_PRINT_STR,\ - gpu_sim_cycle + gpu_tot_sim_cycle,\ + m_shader->get_gpu()->gpu_sim_cycle + m_shader->get_gpu()->gpu_tot_sim_cycle,\ Trace::trace_streams_str[Trace::WARP_SCHEDULER],\ get_sid(),\ m_id );\ diff --git a/src/gpgpu-sim/stat-tool.cc b/src/gpgpu-sim/stat-tool.cc index 6a4c75b..35a4cc3 100644 --- a/src/gpgpu-sim/stat-tool.cc +++ b/src/gpgpu-sim/stat-tool.cc @@ -37,6 +37,7 @@ #include <map> #include <algorithm> #include <string> +#include "../../libcuda/gpgpu_context.h" //////////////////////////////////////////////////////////////////////////////// @@ -110,12 +111,10 @@ void spill_log_to_file (FILE *fout, int final, unsigned long long current_cycle //////////////////////////////////////////////////////////////////////////////// -unsigned translate_pc_to_ptxlineno(unsigned pc); - static int n_thread_CFloggers = 0; static thread_CFlocality** thread_CFlogger = NULL; -void create_thread_CFlogger( int n_loggers, int n_threads, address_type start_pc, unsigned long long logging_interval) +void create_thread_CFlogger(gpgpu_context* ctx, int n_loggers, int n_threads, address_type start_pc, unsigned long long logging_interval) { destroy_thread_CFlogger(); @@ -126,7 +125,7 @@ void create_thread_CFlogger( int n_loggers, int n_threads, address_type start_pc char buffer[32]; for (int i = 0; i < n_thread_CFloggers; i++) { snprintf(buffer, 32, "%02d", i); - thread_CFlogger[i] = new thread_CFlocality( name_tpl + buffer, logging_interval, n_threads, start_pc); + thread_CFlogger[i] = new thread_CFlocality( ctx, name_tpl + buffer, logging_interval, n_threads, start_pc); if (logging_interval != 0) { add_snap_shot_trigger(thread_CFlogger[i]); add_spill_log(thread_CFlogger[i]); @@ -368,10 +367,10 @@ static int s_cache_access_logger_n_types = 0; static std::vector<linear_histogram_logger> s_cache_access_logger; enum cache_access_logger_types { - NORMAL, TEXTURE, CONSTANT, INSTRUCTION + NORMALS, TEXTURE, CONSTANT, INSTRUCTION }; -int get_shader_normal_cache_id() { return NORMAL; } +int get_shader_normal_cache_id() { return NORMALS; } int get_shader_texture_cache_id() { return TEXTURE; } int get_shader_constant_cache_id() { return CONSTANT; } int get_shader_instruction_cache_id() { return INSTRUCTION; } @@ -394,7 +393,7 @@ void shader_cache_access_log( int logger_id, int type, int miss) { if (s_cache_access_logger_n_types == 0) return; if (logger_id < 0) return; - assert(type == NORMAL || type == TEXTURE || type == CONSTANT || type == INSTRUCTION); + assert(type == NORMALS || type == TEXTURE || type == CONSTANT || type == INSTRUCTION); assert(miss == 0 || miss == 1); s_cache_access_logger[logger_id].log(2 * type + miss); @@ -404,7 +403,7 @@ void shader_cache_access_unlog( int logger_id, int type, int miss) { if (s_cache_access_logger_n_types == 0) return; if (logger_id < 0) return; - assert(type == NORMAL || type == TEXTURE || type == CONSTANT || type == INSTRUCTION); + assert(type == NORMALS || type == TEXTURE || type == CONSTANT || type == INSTRUCTION); assert(miss == 0 || miss == 1); s_cache_access_logger[logger_id].unlog(2 * type + miss); @@ -477,22 +476,24 @@ void shader_CTA_count_visualizer_gzprint( gzFile fout ) //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -thread_insn_span::thread_insn_span(unsigned long long cycle) +thread_insn_span::thread_insn_span(unsigned long long cycle, gpgpu_context* ctx) : m_cycle(cycle), #if (tr1_hash_map_ismap == 1) m_insn_span_count() #else m_insn_span_count(32*1024) #endif -{ +{ + gpgpu_ctx = ctx; } thread_insn_span::~thread_insn_span() { } -thread_insn_span::thread_insn_span(const thread_insn_span& other) +thread_insn_span::thread_insn_span(const thread_insn_span& other, gpgpu_context* ctx) : m_cycle(other.m_cycle), - m_insn_span_count(other.m_insn_span_count) + m_insn_span_count(other.m_insn_span_count) { + gpgpu_ctx = ctx; } thread_insn_span& thread_insn_span::operator=(const thread_insn_span& other) @@ -551,7 +552,7 @@ void thread_insn_span::print_sparse_histo(FILE *fout) const int n_printed_entries = 0; span_count_map::const_iterator i_sc = m_insn_span_count.begin(); for (; i_sc != m_insn_span_count.end(); ++i_sc) { - unsigned ptx_lineno = translate_pc_to_ptxlineno(i_sc->first); + unsigned ptx_lineno = gpgpu_ctx->translate_pc_to_ptxlineno(i_sc->first); fprintf(fout, "%u %d ", ptx_lineno, i_sc->second); n_printed_entries++; } @@ -566,7 +567,7 @@ void thread_insn_span::print_sparse_histo(gzFile fout) const int n_printed_entries = 0; span_count_map::const_iterator i_sc = m_insn_span_count.begin(); for (; i_sc != m_insn_span_count.end(); ++i_sc) { - unsigned ptx_lineno = translate_pc_to_ptxlineno(i_sc->first); + unsigned ptx_lineno = gpgpu_ctx->translate_pc_to_ptxlineno(i_sc->first); gzprintf(fout, "%u %d ", ptx_lineno, i_sc->second); n_printed_entries++; } @@ -578,14 +579,14 @@ void thread_insn_span::print_sparse_histo(gzFile fout) const //////////////////////////////////////////////////////////////////////////////// -thread_CFlocality::thread_CFlocality(std::string name, +thread_CFlocality::thread_CFlocality( gpgpu_context* ctx, std::string name, unsigned long long snap_shot_interval, int nthreads, address_type start_pc, unsigned long long start_cycle) : snap_shot_trigger(snap_shot_interval), m_name(name), m_nthreads(nthreads), m_thread_pc(nthreads, start_pc), m_cycle(start_cycle), - m_thd_span(start_cycle) + m_thd_span(start_cycle, ctx) { std::fill(m_thread_pc.begin(), m_thread_pc.end(), -1); // so that hw thread with no work assigned will not clobber results } diff --git a/src/gpgpu-sim/stat-tool.h b/src/gpgpu-sim/stat-tool.h index 5646f01..67b3923 100644 --- a/src/gpgpu-sim/stat-tool.h +++ b/src/gpgpu-sim/stat-tool.h @@ -35,6 +35,7 @@ #include <stdio.h> #include <zlib.h> +class gpgpu_context; ///////////////////////////////////////////////////////////////////////////////////// // logger snapshot trigger: // - automate the snap_shot part of loggers to avoid modifying simulation loop everytime @@ -80,8 +81,8 @@ public: class thread_insn_span { public: - thread_insn_span(unsigned long long cycle); - thread_insn_span(const thread_insn_span& other); + thread_insn_span(unsigned long long cycle, gpgpu_context* ctx); + thread_insn_span(const thread_insn_span& other, gpgpu_context* ctx); ~thread_insn_span(); thread_insn_span& operator=(const thread_insn_span& other); @@ -94,7 +95,8 @@ public: void print_sparse_histo(FILE *fout) const; void print_sparse_histo(gzFile fout) const; -private: +private: + gpgpu_context* gpgpu_ctx; typedef tr1_hash_map<address_type, int> span_count_map; unsigned long long m_cycle; span_count_map m_insn_span_count; @@ -102,7 +104,7 @@ private: class thread_CFlocality : public snap_shot_trigger, public spill_log_interface { public: - thread_CFlocality(std::string name, unsigned long long snap_shot_interval, + thread_CFlocality(gpgpu_context* ctx, std::string name, unsigned long long snap_shot_interval, int nthreads, address_type start_pc, unsigned long long start_cycle = 0); ~thread_CFlocality(); @@ -270,7 +272,7 @@ void try_snap_shot (unsigned long long current_cycle); void set_spill_interval (unsigned long long interval); void spill_log_to_file (FILE *fout, int final, unsigned long long current_cycle); -void create_thread_CFlogger( int n_loggers, int n_threads, address_type start_pc, unsigned long long logging_interval); +void create_thread_CFlogger(gpgpu_context* ctx, int n_loggers, int n_threads, address_type start_pc, unsigned long long logging_interval); void destroy_thread_CFlogger( ); void cflog_update_thread_pc( int logger_id, int thread_id, address_type pc ); void cflog_snapshot( int logger_id, unsigned long long cycle ); diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index 9e2bfa2..816159f 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -35,32 +35,30 @@ #include "gpgpu-sim/gpu-sim.h" #include "gpgpu-sim/icnt_wrapper.h" #include "stream_manager.h" - -#include <pthread.h> -#include <semaphore.h> +#include "../libcuda/gpgpu_context.h" #define MAX(a,b) (((a)>(b))?(a):(b)) +static int sg_argc = 3; +static const char *sg_argv[] = {"", "-config","gpgpusim.config"}; -struct gpgpu_ptx_sim_arg *grid_params; - -sem_t g_sim_signal_start; -sem_t g_sim_signal_finish; -sem_t g_sim_signal_exit; -time_t g_simulation_starttime; -pthread_t g_simulation_thread; - -gpgpu_sim_config g_the_gpu_config; -gpgpu_sim *g_the_gpu; -stream_manager *g_stream_manager; - +GPGPUsim_ctx* the_gpgpusim = NULL; +GPGPUsim_ctx* GPGPUsim_ctx_ptr(){ + if(the_gpgpusim == NULL) + the_gpgpusim = GPGPU_Context()->the_gpgpusim; -static int sg_argc = 3; -static const char *sg_argv[] = {"", "-config","gpgpusim.config"}; + return the_gpgpusim; +} +class gpgpu_sim* g_the_gpu() { + return GPGPUsim_ctx_ptr()->g_the_gpu; +} +class stream_manager* g_stream_manager() { + return GPGPUsim_ctx_ptr()->g_stream_manager; +} static void print_simulation_time(); @@ -69,29 +67,26 @@ void *gpgpu_sim_thread_sequential(void*) // at most one kernel running at a time bool done; do { - sem_wait(&g_sim_signal_start); + sem_wait(&(GPGPUsim_ctx_ptr()->g_sim_signal_start)); done = true; - if( g_the_gpu->get_more_cta_left() ) { + if( GPGPUsim_ctx_ptr()->g_the_gpu->get_more_cta_left() ) { done = false; - g_the_gpu->init(); - while( g_the_gpu->active() ) { - g_the_gpu->cycle(); - g_the_gpu->deadlock_check(); + GPGPUsim_ctx_ptr()->g_the_gpu->init(); + while( GPGPUsim_ctx_ptr()->g_the_gpu->active() ) { + GPGPUsim_ctx_ptr()->g_the_gpu->cycle(); + GPGPUsim_ctx_ptr()->g_the_gpu->deadlock_check(); } - g_the_gpu->print_stats(); - g_the_gpu->update_stats(); + GPGPUsim_ctx_ptr()->g_the_gpu->print_stats(); + GPGPUsim_ctx_ptr()->g_the_gpu->update_stats(); print_simulation_time(); } - sem_post(&g_sim_signal_finish); + sem_post(&(GPGPUsim_ctx_ptr()->g_sim_signal_finish)); } while(!done); - sem_post(&g_sim_signal_exit); + sem_post(&(GPGPUsim_ctx_ptr()->g_sim_signal_exit)); return NULL; } -pthread_mutex_t g_sim_lock = PTHREAD_MUTEX_INITIALIZER; -bool g_sim_active = false; -bool g_sim_done = true; -bool break_limit = false; + static void termination_callback() { @@ -108,19 +103,19 @@ void *gpgpu_sim_thread_concurrent(void*) printf("GPGPU-Sim: *** simulation thread starting and spinning waiting for work ***\n"); fflush(stdout); } - while( g_stream_manager->empty_protected() && !g_sim_done ) + while( GPGPUsim_ctx_ptr()->g_stream_manager->empty_protected() && !GPGPUsim_ctx_ptr()->g_sim_done ) ; if(g_debug_execution >= 3) { printf("GPGPU-Sim: ** START simulation thread (detected work) **\n"); - g_stream_manager->print(stdout); + GPGPUsim_ctx_ptr()->g_stream_manager->print(stdout); fflush(stdout); } - pthread_mutex_lock(&g_sim_lock); - g_sim_active = true; - pthread_mutex_unlock(&g_sim_lock); + pthread_mutex_lock(&(GPGPUsim_ctx_ptr()->g_sim_lock)); + GPGPUsim_ctx_ptr()->g_sim_active = true; + pthread_mutex_unlock(&(GPGPUsim_ctx_ptr()->g_sim_lock)); bool active = false; bool sim_cycles = false; - g_the_gpu->init(); + GPGPUsim_ctx_ptr()->g_the_gpu->init(); do { // check if a kernel has completed // launch operation on device if one is pending and can be run @@ -132,70 +127,70 @@ void *gpgpu_sim_thread_concurrent(void*) // another kernel, the gpu is not re-initialized and the inter-kernel // behaviour may be incorrect. Check that a kernel has finished and // no other kernel is currently running. - if(g_stream_manager->operation(&sim_cycles) && !g_the_gpu->active()) + if(GPGPUsim_ctx_ptr()->g_stream_manager->operation(&sim_cycles) && !GPGPUsim_ctx_ptr()->g_the_gpu->active()) break; //functional simulation - if( g_the_gpu->is_functional_sim()) { - kernel_info_t * kernel = g_the_gpu->get_functional_kernel(); + if( GPGPUsim_ctx_ptr()->g_the_gpu->is_functional_sim()) { + kernel_info_t * kernel = GPGPUsim_ctx_ptr()->g_the_gpu->get_functional_kernel(); assert(kernel); - gpgpu_cuda_ptx_sim_main_func(*kernel); - g_the_gpu->finish_functional_sim(kernel); + GPGPUsim_ctx_ptr()->gpgpu_ctx->func_sim->gpgpu_cuda_ptx_sim_main_func(*kernel); + GPGPUsim_ctx_ptr()->g_the_gpu->finish_functional_sim(kernel); } //performance simulation - if( g_the_gpu->active() ) { - g_the_gpu->cycle(); - sim_cycles = true; - g_the_gpu->deadlock_check(); + if( GPGPUsim_ctx_ptr()->g_the_gpu->active() ) { + GPGPUsim_ctx_ptr()->g_the_gpu->cycle(); + sim_cycles = true; + GPGPUsim_ctx_ptr()->g_the_gpu->deadlock_check(); }else { - if(g_the_gpu->cycle_insn_cta_max_hit()){ - g_stream_manager->stop_all_running_kernels(); - g_sim_done = true; - break_limit = true; + if(GPGPUsim_ctx_ptr()->g_the_gpu->cycle_insn_cta_max_hit()){ + GPGPUsim_ctx_ptr()->g_stream_manager->stop_all_running_kernels(); + GPGPUsim_ctx_ptr()->g_sim_done = true; + GPGPUsim_ctx_ptr()->break_limit = true; } } - active=g_the_gpu->active() || !g_stream_manager->empty_protected(); + active=GPGPUsim_ctx_ptr()->g_the_gpu->active() || !(GPGPUsim_ctx_ptr()->g_stream_manager->empty_protected()); - } while( active && !g_sim_done); + } while( active && !GPGPUsim_ctx_ptr()->g_sim_done); if(g_debug_execution >= 3) { printf("GPGPU-Sim: ** STOP simulation thread (no work) **\n"); fflush(stdout); } if(sim_cycles) { - g_the_gpu->print_stats(); - g_the_gpu->update_stats(); + GPGPUsim_ctx_ptr()->g_the_gpu->print_stats(); + GPGPUsim_ctx_ptr()->g_the_gpu->update_stats(); print_simulation_time(); } - pthread_mutex_lock(&g_sim_lock); - g_sim_active = false; - pthread_mutex_unlock(&g_sim_lock); - } while( !g_sim_done ); + pthread_mutex_lock(&(GPGPUsim_ctx_ptr()->g_sim_lock)); + GPGPUsim_ctx_ptr()->g_sim_active = false; + pthread_mutex_unlock(&(GPGPUsim_ctx_ptr()->g_sim_lock)); + } while( !GPGPUsim_ctx_ptr()->g_sim_done ); printf("GPGPU-Sim: *** simulation thread exiting ***\n"); fflush(stdout); - if(break_limit) { + if(GPGPUsim_ctx_ptr()->break_limit) { printf("GPGPU-Sim: ** break due to reaching the maximum cycles (or instructions) **\n"); exit(1); } - sem_post(&g_sim_signal_exit); + sem_post(&(GPGPUsim_ctx_ptr()->g_sim_signal_exit)); return NULL; } void synchronize() { printf("GPGPU-Sim: synchronize waiting for inactive GPU simulation\n"); - g_stream_manager->print(stdout); + GPGPUsim_ctx_ptr()->g_stream_manager->print(stdout); fflush(stdout); // sem_wait(&g_sim_signal_finish); bool done = false; do { - pthread_mutex_lock(&g_sim_lock); - done = ( g_stream_manager->empty() && !g_sim_active ) || g_sim_done; - pthread_mutex_unlock(&g_sim_lock); + pthread_mutex_lock(&(GPGPUsim_ctx_ptr()->g_sim_lock)); + done = ( GPGPUsim_ctx_ptr()->g_stream_manager->empty() && !GPGPUsim_ctx_ptr()->g_sim_active ) || GPGPUsim_ctx_ptr()->g_sim_done; + pthread_mutex_unlock(&(GPGPUsim_ctx_ptr()->g_sim_lock)); } while (!done); printf("GPGPU-Sim: detected inactive GPU simulation thread\n"); fflush(stdout); @@ -204,29 +199,28 @@ void synchronize() void exit_simulation() { - g_sim_done=true; + GPGPUsim_ctx_ptr()->g_sim_done=true; printf("GPGPU-Sim: exit_simulation called\n"); fflush(stdout); - sem_wait(&g_sim_signal_exit); + sem_wait(&(GPGPUsim_ctx_ptr()->g_sim_signal_exit)); printf("GPGPU-Sim: simulation thread signaled exit\n"); fflush(stdout); } -extern bool g_cuda_launch_blocking; - -gpgpu_sim *gpgpu_ptx_sim_init_perf() +gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() { srand(1); print_splash(); - read_sim_environment_variables(); - read_parser_environment_variables(); + func_sim->read_sim_environment_variables(); + ptx_parser->read_parser_environment_variables(); option_parser_t opp = option_parser_create(); ptx_reg_options(opp); - ptx_opcocde_latency_options(opp); + func_sim->ptx_opcocde_latency_options(opp); icnt_reg_options(opp); - g_the_gpu_config.reg_options(opp); // register GPU microrachitecture options + GPGPUsim_ctx_ptr()->g_the_gpu_config = new gpgpu_sim_config(this); + GPGPUsim_ctx_ptr()->g_the_gpu_config->reg_options(opp); // register GPU microrachitecture options option_parser_cmdline(opp, sg_argc, sg_argv); // parse configuration options fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n"); @@ -234,28 +228,28 @@ gpgpu_sim *gpgpu_ptx_sim_init_perf() // Set the Numeric locale to a standard locale where a decimal point is a "dot" not a "comma" // so it does the parsing correctly independent of the system environment variables assert(setlocale(LC_NUMERIC,"C")); - g_the_gpu_config.init(); + GPGPUsim_ctx_ptr()->g_the_gpu_config->init(); - g_the_gpu = new gpgpu_sim(g_the_gpu_config); - g_stream_manager = new stream_manager(g_the_gpu,g_cuda_launch_blocking); + GPGPUsim_ctx_ptr()->g_the_gpu = new gpgpu_sim(*(GPGPUsim_ctx_ptr()->g_the_gpu_config), this); + GPGPUsim_ctx_ptr()->g_stream_manager = new stream_manager((GPGPUsim_ctx_ptr()->g_the_gpu), func_sim->g_cuda_launch_blocking); - g_simulation_starttime = time((time_t *)NULL); + GPGPUsim_ctx_ptr()->g_simulation_starttime = time((time_t *)NULL); - sem_init(&g_sim_signal_start,0,0); - sem_init(&g_sim_signal_finish,0,0); - sem_init(&g_sim_signal_exit,0,0); + sem_init(&(GPGPUsim_ctx_ptr()->g_sim_signal_start),0,0); + sem_init(&(GPGPUsim_ctx_ptr()->g_sim_signal_finish),0,0); + sem_init(&(GPGPUsim_ctx_ptr()->g_sim_signal_exit),0,0); - return g_the_gpu; + return GPGPUsim_ctx_ptr()->g_the_gpu; } void start_sim_thread(int api) { - if( g_sim_done ) { - g_sim_done = false; + if( GPGPUsim_ctx_ptr()->g_sim_done ) { + GPGPUsim_ctx_ptr()->g_sim_done = false; if( api == 1 ) { - pthread_create(&g_simulation_thread,NULL,gpgpu_sim_thread_concurrent,NULL); + pthread_create(&(GPGPUsim_ctx_ptr()->g_simulation_thread),NULL,gpgpu_sim_thread_concurrent,NULL); } else { - pthread_create(&g_simulation_thread,NULL,gpgpu_sim_thread_sequential,NULL); + pthread_create(&(GPGPUsim_ctx_ptr()->g_simulation_thread),NULL,gpgpu_sim_thread_sequential,NULL); } } } @@ -264,7 +258,7 @@ void print_simulation_time() { time_t current_time, difference, d, h, m, s; current_time = time((time_t *)NULL); - difference = MAX(current_time - g_simulation_starttime, 1); + difference = MAX(current_time - GPGPUsim_ctx_ptr()->g_simulation_starttime, 1); d = difference/(3600*24); h = difference/3600 - 24*d; @@ -274,16 +268,16 @@ void print_simulation_time() fflush(stderr); printf("\n\ngpgpu_simulation_time = %u days, %u hrs, %u min, %u sec (%u sec)\n", (unsigned)d, (unsigned)h, (unsigned)m, (unsigned)s, (unsigned)difference ); - printf("gpgpu_simulation_rate = %u (inst/sec)\n", (unsigned)(g_the_gpu->gpu_tot_sim_insn / difference) ); - printf("gpgpu_simulation_rate = %u (cycle/sec)\n", (unsigned)(gpu_tot_sim_cycle / difference) ); + printf("gpgpu_simulation_rate = %u (inst/sec)\n", (unsigned)(GPGPUsim_ctx_ptr()->g_the_gpu->gpu_tot_sim_insn / difference) ); + printf("gpgpu_simulation_rate = %u (cycle/sec)\n", (unsigned)(GPGPUsim_ctx_ptr()->g_the_gpu->gpu_tot_sim_cycle / difference) ); fflush(stdout); } int gpgpu_opencl_ptx_sim_main_perf( kernel_info_t *grid ) { - g_the_gpu->launch(grid); - sem_post(&g_sim_signal_start); - sem_wait(&g_sim_signal_finish); + GPGPUsim_ctx_ptr()->g_the_gpu->launch(grid); + sem_post(&(GPGPUsim_ctx_ptr()->g_sim_signal_start)); + sem_wait(&(GPGPUsim_ctx_ptr()->g_sim_signal_finish)); return 0; } @@ -291,7 +285,7 @@ int gpgpu_opencl_ptx_sim_main_perf( kernel_info_t *grid ) /*! * This function call the CUDA PTX functional simulator */ -int gpgpu_opencl_ptx_sim_main_func( kernel_info_t *grid ) +int cuda_sim::gpgpu_opencl_ptx_sim_main_func( kernel_info_t *grid ) { //calling the CUDA PTX simulator, sending the kernel by reference and a flag set to true, //the flag used by the function to distinguish OpenCL calls from the CUDA simulation calls which diff --git a/src/gpgpusim_entrypoint.h b/src/gpgpusim_entrypoint.h index bf03f03..887b3c8 100644 --- a/src/gpgpusim_entrypoint.h +++ b/src/gpgpusim_entrypoint.h @@ -29,16 +29,59 @@ #define GPGPUSIM_ENTRYPOINT_H_INCLUDED #include "abstract_hardware_model.h" - +#include <pthread.h> +#include <semaphore.h> #include <time.h> -extern time_t g_simulation_starttime; +//extern time_t g_simulation_starttime; +class gpgpu_context; + +class GPGPUsim_ctx { + public: + GPGPUsim_ctx(gpgpu_context* ctx) { + g_sim_active = false; + g_sim_done = true; + break_limit = false; + g_sim_lock = PTHREAD_MUTEX_INITIALIZER; + + g_the_gpu_config=NULL; + g_the_gpu=NULL; + g_stream_manager=NULL; + the_cude_device=NULL; + the_context=NULL; + gpgpu_ctx = ctx; + } + + //struct gpgpu_ptx_sim_arg *grid_params; + + sem_t g_sim_signal_start; + sem_t g_sim_signal_finish; + sem_t g_sim_signal_exit; + time_t g_simulation_starttime; + pthread_t g_simulation_thread; + class gpgpu_sim_config *g_the_gpu_config; + class gpgpu_sim *g_the_gpu; + class stream_manager *g_stream_manager; + + struct _cuda_device_id *the_cude_device; + struct CUctx_st* the_context; + gpgpu_context* gpgpu_ctx; + + + pthread_mutex_t g_sim_lock; + bool g_sim_active; + bool g_sim_done; + bool break_limit; + +}; -class gpgpu_sim *gpgpu_ptx_sim_init_perf(); void start_sim_thread(int api); +class gpgpu_sim* g_the_gpu(); +struct GPGPUsim_ctx* GPGPUsim_ctx_ptr(); +class stream_manager* g_stream_manager(); + int gpgpu_opencl_ptx_sim_main_perf( kernel_info_t *grid ); -int gpgpu_opencl_ptx_sim_main_func( kernel_info_t *grid ); #endif diff --git a/src/intersim2/Makefile b/src/intersim2/Makefile index 7d10b3f..3eeeb70 100644 --- a/src/intersim2/Makefile +++ b/src/intersim2/Makefile @@ -48,6 +48,7 @@ CPPFLAGS += -O3 endif CPPFLAGS += -g CPPFLAGS += -fPIC +CPPFLAGS += -I$(CUDA_INSTALL_PATH)/include LFLAGS += diff --git a/src/option_parser.cc b/src/option_parser.cc index 497316f..7d747f0 100644 --- a/src/option_parser.cc +++ b/src/option_parser.cc @@ -100,8 +100,7 @@ public: } try { ss >> m_variable; - } catch (stringstream::failure &e) { - } catch (exception &e) { + } catch (exception &e) { return false; } m_isParsed = true; diff --git a/src/stream_manager.cc b/src/stream_manager.cc index 6cd62a2..be3dd71 100644 --- a/src/stream_manager.cc +++ b/src/stream_manager.cc @@ -29,6 +29,7 @@ #include "gpgpusim_entrypoint.h" #include "cuda-sim/cuda-sim.h" #include "gpgpu-sim/gpu-sim.h" +#include "../libcuda/gpgpu_context.h" unsigned CUstream_st::sm_next_stream_uid = 0; @@ -150,13 +151,13 @@ bool stream_operation::do_operation( gpgpu_sim *gpu ) case stream_memcpy_to_symbol: if(g_debug_execution >= 3) printf("memcpy to symbol\n"); - gpgpu_ptx_sim_memcpy_symbol(m_symbol,m_host_address_src,m_cnt,m_offset,1,gpu); + gpu->gpgpu_ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol(m_symbol,m_host_address_src,m_cnt,m_offset,1,gpu); m_stream->record_next_done(); break; case stream_memcpy_from_symbol: if(g_debug_execution >= 3) printf("memcpy from symbol\n"); - gpgpu_ptx_sim_memcpy_symbol(m_symbol,m_host_address_dst,m_cnt,m_offset,0,gpu); + gpu->gpgpu_ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol(m_symbol,m_host_address_dst,m_cnt,m_offset,0,gpu); m_stream->record_next_done(); break; case stream_kernel_launch: @@ -190,7 +191,7 @@ bool stream_operation::do_operation( gpgpu_sim *gpu ) case stream_event: { printf("event update\n"); time_t wallclock = time((time_t *)NULL); - m_event->update( gpu_tot_sim_cycle, wallclock ); + m_event->update( gpu->gpu_tot_sim_cycle, wallclock ); m_stream->record_next_done(); } break; diff --git a/src/trace.h b/src/trace.h index a79b4a0..0b96dcf 100644 --- a/src/trace.h +++ b/src/trace.h @@ -31,9 +31,6 @@ #ifndef __TRACE_H__ #define __TRACE_H__ -extern unsigned long long gpu_sim_cycle; -extern unsigned long long gpu_tot_sim_cycle; - namespace Trace { #define TS_TUP_BEGIN(X) enum X { @@ -63,17 +60,26 @@ namespace Trace { #define DPRINTF(x, ...) do {\ if (DTRACE(x)) {\ printf( SIM_PRINT_STR,\ - gpu_sim_cycle + gpu_tot_sim_cycle,\ + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle,\ Trace::trace_streams_str[Trace::x] );\ printf(__VA_ARGS__);\ }\ } while (0) +#define DPRINTFG(x, ...) do {\ + if (DTRACE(x)) {\ + printf( SIM_PRINT_STR,\ + gpu_sim_cycle + gpu_tot_sim_cycle,\ + Trace::trace_streams_str[Trace::x] );\ + printf(__VA_ARGS__);\ + }\ +} while (0) #else #define DTRACE(x) (false) #define DPRINTF(x, ...) do {} while (0) +#define DPRINTFG(x, ...) do {} while (0) #endif diff --git a/version_detection.mk b/version_detection.mk index 00a86c0..ee71a62 100644 --- a/version_detection.mk +++ b/version_detection.mk @@ -33,8 +33,9 @@ GPGPUSIM_VERSION=$(shell cat $(GPGPUSIM_ROOT)/version | awk '/Version/ {print $$ #Detect Git branch and commit # GIT_COMMIT := $(shell git log -n 1 | head -1 | sed -re 's/commit (.*)/\1/') -GIT_FILES_CHANGED := $(shell git diff --numstat --cached && git diff --numstat | wc | sed -re 's/^\s+([0-9]+).*/\1/') -GPGPUSIM_BUILD := "gpgpu-sim_git-commit-$(GIT_COMMIT)_modified_$(GIT_FILES_CHANGED)" +GIT_FILES_CHANGED_A:=$(shell git diff --numstat | wc | sed -re 's/^\s+([0-9]+).*/\1./') +GIT_FILES_CHANGED:= $(GIT_FILES_CHANGED_A)$(shell git diff --numstat --cached | wc | sed -re 's/^\s+([0-9]+).*/\1/') +GPGPUSIM_BUILD := gpgpu-sim_git-commit-$(GIT_COMMIT)_modified_$(GIT_FILES_CHANGED) endif # Detect CUDA Runtime Version |
