seanhalle@0: #include seanhalle@0: #include seanhalle@0: #include seanhalle@0: seanhalle@0: #include "Matrix_Mult.h" seanhalle@0: #include "Reo__Matrix_Mult/Reo__Matrix_Mult.h" seanhalle@0: seanhalle@0: void set_up_performance_counters(); seanhalle@0: seanhalle@0: // ============================================================================= seanhalle@0: seanhalle@0: int NUM_ITER; seanhalle@0: seanhalle@0: seanhalle@0: int main(int argc, char **argv) seanhalle@0: { Matrix *leftMatrix, *rightMatrix, *resultMatrix; seanhalle@0: ParamBag *paramBag; seanhalle@1: MatrixMultWorkUnit **workUnits; seanhalle@1: VPParams *vpParams, **vpParamsArray; seanhalle@1: // ProdParams *prodParams; seanhalle@1: // ConsParams *consParams; seanhalle@1: int32 numUnitsToMake, vpIdx; seanhalle@1: PRProcess *matrixMultProcess; seanhalle@0: seanhalle@1: DEBUG__printf(TRUE, "arguments -- numIter: %s | path: %s", argv[1], argv[2] ); seanhalle@1: if(argc < 3) {printf("give: num iter and path to param file on cmd line\n"); exit(1);} seanhalle@0: NUM_ITER = atoi(argv[1]); seanhalle@1: numUnitsToMake = NUM_PROD; //defined by Reo circuit generator seanhalle@1: seanhalle@1: printf("[reo] Settings: %i workers, %i iterations | file: %s \n", NUM_PROD, NUM_ITER, argv[2]); seanhalle@1: seanhalle@1: set_up_performance_counters(); seanhalle@0: seanhalle@0: //read parameters, from file whose path is given on command line seanhalle@0: paramBag = makeParamBag(); seanhalle@0: readParamFileIntoBag( argv[2], paramBag ); seanhalle@0: initialize_Input_Matrices_Via( &leftMatrix, &rightMatrix, paramBag ); seanhalle@0: seanhalle@0: seanhalle@1: PR__start(); seanhalle@1: PR__set_app_info( "matrix multiply prod cons in Reo" ); seanhalle@1: ParamStruc *inputInfo = getParamFromBag( "inputInfo", paramBag ); seanhalle@1: PR__set_input_info( inputInfo->strValue ); seanhalle@0: seanhalle@1: resultMatrix = PR__malloc( sizeof(Matrix) ); seanhalle@1: resultMatrix->array = PR__malloc( leftMatrix->numRows * rightMatrix->numCols * sizeof(double) ); seanhalle@1: resultMatrix->numCols = rightMatrix->numCols; seanhalle@1: resultMatrix->numRows = leftMatrix->numRows; seanhalle@1: workUnits = divideWork( leftMatrix, rightMatrix, resultMatrix, seanhalle@1: numUnitsToMake ); seanhalle@0: seanhalle@1: /* For now, don't need any params inside producer function other than seanhalle@1: * the work unit. Also, don't need any params at all inside cons function. seanhalle@1: * So, just send the array of work units to the seed Fn, which will pass it seanhalle@1: * along to the create_VP part of circuit creation, which will copy the seanhalle@1: * elements of the array into the param structs given as initData to the seanhalle@1: * VPs, as they are created. seanhalle@1: *Need a dummy work unit added to end of work-unit array, to avoid a seg seanhalle@1: * fault -- just did a bad hack inside divideWork. seanhalle@1: //Now, create params struct for each producer -- holds work unit seanhalle@1: for( vpIdx=0; vpIdxinitData = prodParams; seanhalle@1: vpParamsArray[vpIdx] = vpParams; seanhalle@1: } seanhalle@1: //create params for consumer seanhalle@1: seanhalle@1: vpParams = PR__malloc( sizeof(VPParams) ); seanhalle@1: = malloc( sizeof(ProdParams) ); seanhalle@1: seanhalle@1: vpParams->initData = seanhalle@1: vpParamsArray[vpIdx] = vpParams; //this last entry is for the consumer seanhalle@1: */ seanhalle@1: seanhalle@1: matrixMultProcess = PR__create_process( &matrix_mult__seed_Fn, seanhalle@1: workUnits ); seanhalle@1: seanhalle@1: PR__wait_for_process_to_end(matrixMultProcess); seanhalle@1: PR__wait_for_all_activity_to_end(); seanhalle@0: fflush(stdout); seanhalle@1: PR__shutdown(); seanhalle@0: seanhalle@0: exit(0); seanhalle@0: } seanhalle@0: seanhalle@0: // ============================================================================= seanhalle@0: seanhalle@0: /*Initializes the performance counters, and opens the file descriptors used seanhalle@0: * to read from the performance counters seanhalle@0: */ seanhalle@0: void set_up_performance_counters() { seanhalle@0: int i; seanhalle@0: seanhalle@0: #ifdef MEASURE_PERF seanhalle@0: //setup performance counters seanhalle@0: struct perf_event_attr hw_event; seanhalle@0: memset(&hw_event,0,sizeof(hw_event)); seanhalle@0: hw_event.type = PERF_TYPE_HARDWARE; seanhalle@0: hw_event.size = sizeof(hw_event); seanhalle@0: hw_event.disabled = 0; seanhalle@0: hw_event.freq = 0; seanhalle@0: hw_event.inherit = 1; /* children inherit it */ seanhalle@0: hw_event.pinned = 1; /* must always be on PMU */ seanhalle@0: hw_event.exclusive = 0; /* only group on PMU */ seanhalle@0: hw_event.exclude_user = 0; /* don't count user */ seanhalle@0: hw_event.exclude_kernel = 1; /* ditto kernel */ seanhalle@0: hw_event.exclude_hv = 1; /* ditto hypervisor */ seanhalle@0: hw_event.exclude_idle = 1; /* don't count when idle */ seanhalle@0: hw_event.mmap = 0; /* include mmap data */ seanhalle@0: hw_event.comm = 0; /* include comm data */ seanhalle@0: seanhalle@0: for( i = 0; i < NUM_CORES; i++ ) seanhalle@0: { seanhalle@0: hw_event.config = PERF_COUNT_HW_CPU_CYCLES; //cycles seanhalle@0: cycles_counter_fd[i] = syscall(__NR_perf_event_open, &hw_event, seanhalle@0: 0,//pid_t pid, seanhalle@0: i,//int cpu, seanhalle@0: -1,//int group_fd, seanhalle@0: 0//unsigned long flags seanhalle@0: ); seanhalle@0: if (cycles_counter_fd[i]<0) { seanhalle@0: fprintf(stderr,"On core %d: ",i); seanhalle@0: perror("Failed to open cycles counter"); seanhalle@0: } seanhalle@0: } seanhalle@0: seanhalle@0: int cycles_counter_main_fd; seanhalle@0: hw_event.config = PERF_COUNT_HW_CPU_CYCLES; //cycles seanhalle@0: hw_event.exclude_kernel=0; seanhalle@0: cycles_counter_main_fd = syscall(__NR_perf_event_open, &hw_event, seanhalle@0: 0,//pid_t pid, seanhalle@0: -1,//int cpu, seanhalle@0: -1,//int group_fd, seanhalle@0: 0//unsigned long flags seanhalle@0: ); seanhalle@0: if (cycles_counter_main_fd<0) { seanhalle@0: perror("Failed to open main cycles counter"); seanhalle@0: } seanhalle@0: seanhalle@0: #endif seanhalle@0: } seanhalle@0: