void send_patch_info(int *patch_w, int *patch_h, int *patch_no, int *total_nr_patches, int **spu_patch_id_vector, pixel_t **patches_to_send, int *rand_seed, int *overlap_spu, int ***min_borders) { int i; for (i = 0; i < SPU_THREADS; i++) { spe_in_mbox_write(ctx[i], (void *)(patch_w), 1, SPE_MBOX_ANY_NONBLOCKING); spe_in_mbox_write(ctx[i], (void *)(patch_h), 1, SPE_MBOX_ANY_NONBLOCKING); spe_in_mbox_write(ctx[i], (void *)(patch_no), 1, SPE_MBOX_ANY_NONBLOCKING); unsigned int out = (unsigned int)spu_patch_id_vector[i]; spe_in_mbox_write(ctx[i], (void *)(&out), 1, SPE_MBOX_ANY_NONBLOCKING); unsigned int send = (unsigned int)patches_to_send; spe_in_mbox_write(ctx[i], (void *)(&send), 1, SPE_MBOX_ANY_NONBLOCKING); spe_in_mbox_write(ctx[i], (void *)(total_nr_patches), 1, SPE_MBOX_ANY_NONBLOCKING); spe_in_mbox_write(ctx[i], (void *)(&rand_seed[i]), 1, SPE_MBOX_ANY_NONBLOCKING); spe_in_mbox_write(ctx[i], (void *)(overlap_spu), 1, SPE_MBOX_ANY_NONBLOCKING); int j; //printf("PPU: SENDING %d\n", *patch_no-1); for (j = 0; j < (*patch_no)-1; j++) { unsigned int min_borders_address = (unsigned int) min_borders[i][j]; spe_in_mbox_write(ctx[i], (void *)(&min_borders_address), 1, SPE_MBOX_ANY_NONBLOCKING); //printf("PPU: min_borders_address=%p\n", min_borders_address); } } }
double SNRM2( PyArrayObject *pyobj1, unsigned int shadersize, unsigned int *shader ) { Tic(); Operation_t op1; op1.shaderSize = shadersize; op1.EA_shader = shader; op1.obj[0] = pyobj1; op1.num_SPES = speThreads; float *results[6]; unsigned int state = 2, r; unsigned int i; //printf( "Sending states to SPEs\n" ); for ( i = 0 ; i < speThreads ; i++ ) { results[i] = (float *)memalign( 128, ( 4 + 127 ) & ~127 ); r = (unsigned int)results[i]; spe_pointer_addr[i][0] = (unsigned int)&op1; spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); spe_in_mbox_write ( speData[i].spe_ctx, &r, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! //printf( "Waiting for SPEs\n" ); unsigned int checked = 0; while( checked < speThreads ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } float r1 = 0.0f; for ( i = 0 ; i < speThreads ; i++ ) { r1 += results[i][0]; // Cleanup free( results[i] ); } r1 = sqrtf( r1 ); double time = Toc_d(); PrintTicToc( "Finished at ", Toc() ); printf( "Result=%f\n", r1 ); return time; }
/* * Run with one array, with return value */ float run10r( PyArrayObject *pyobj1, unsigned int shadersize, unsigned int *shader ) { Operation_t op1; op1.shaderSize = shadersize; op1.EA_shader = shader; // Determining the number of SPEs op1.num_SPES = _GetNumberOfSPES( pyobj1->numberOfBlocks ); op1.obj[0] = pyobj1; //float *results[6]; unsigned int checked = 0; unsigned int state = 100, r; unsigned int i; for ( i = 0 ; i < op1.num_SPES ; i++ ) { //results[i] = (float *)memalign( 128, ( 4 + 127 ) & ~127 ); r = (unsigned int)resultFloats[i]; spe_pointer_addr[i][0] = (unsigned int)&op1; spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); spe_in_mbox_write ( speData[i].spe_ctx, &r, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! checked = 0; while( checked < op1.num_SPES ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } float r1 = 0.0f; for ( i = 0 ; i < op1.num_SPES ; i++ ) { r1 += resultFloats[i][0]; // Cleanup // free( results[i] ); } return r1; }
void sws_send_message(yuvscaler_t *arg,unsigned int message) { struct yuvscaler_s * arg_ptr; arg_ptr=(struct yuvscaler_s *) arg; while (spe_in_mbox_status(arg_ptr->ctx) == 0); // switch this to a nice little interupt based one spe_in_mbox_write(arg_ptr->ctx,&message,1,SPE_MBOX_ALL_BLOCKING); }
int init( unsigned int numspes ) { // Get the number of available SPEs speThreads = GetNumSPEs(); // Clamp to the defined number of SPEs used if ( speThreads > MAX_SPE_THREADS ) { speThreads = MAX_SPE_THREADS; } if( speThreads > numspes ) { speThreads = numspes; } unsigned int i; // Get dispatcher spe_program_handle_t *dispatcher = spe_image_open( "dispatcher" ); // Initialize threads for( i = 0 ; i < speThreads ; i++ ) { CreateSPEThread( &speData[i], dispatcher, &spe_pointer_addr[i] ); // Sending the SPE its id spe_in_mbox_write ( speData[i].spe_ctx, &i, 1, SPE_MBOX_ALL_BLOCKING ); } return 0; }
/* * Run with one array */ void run10( PyArrayObject *pyobj1, unsigned int shadersize, unsigned int *shader ) { Operation_t op1; op1.shaderSize = shadersize; op1.EA_shader = shader; // Determining the number of SPEs op1.num_SPES = _GetNumberOfSPES( pyobj1->numberOfBlocks ); Printf1( "Using %u SPEs\n", op1.num_SPES ); op1.obj[0] = pyobj1; unsigned int checked = 0; unsigned int state = 0, r; unsigned int i; for ( i = 0 ; i < op1.num_SPES ; i++ ) { spe_pointer_addr[i][0] = (unsigned int)&op1; spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! checked = 0; while( checked < op1.num_SPES ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } }
/* * Run with three arrays, no upload */ void run30nu( unsigned int shaderindex ) { unsigned int checked = 0; unsigned int state = 300 + shaderindex, r; unsigned int i; unsigned int num_SPES = 1; printf( "HERE2\n" ); for ( i = 0 ; i < num_SPES ; i++ ) { spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! checked = 0; while( checked < num_SPES ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } }
///tell the task scheduler we are done with the SPU tasks void SpuLibspe2Support::stopSPU() { // wait for all threads to finish int i; for ( i = 0; i < this->numThreads; i++ ) { unsigned int event = Spu_Mailbox_Event_Shutdown; spe_context_ptr_t context = data[i].context; spe_in_mbox_write(context, &event, 1, SPE_MBOX_ALL_BLOCKING); pthread_join (data[i].pthread, NULL); } // close SPE program spe_image_close(program); // destroy SPE contexts for ( i = 0; i < this->numThreads; i++ ) { if(data[i].context != NULL) { spe_context_destroy (data[i].context); } } m_activeSpuStatus.clear(); }
void handleFakeTrapInt (int chosenSpu) { unsigned int message; spe_out_mbox_read(global_spu_data->spus[chosenSpu].ctx, &(message), 1); pthread_mutex_lock(&fakeTrapLock); sysConsoleWriteChar('F'); sysConsoleWriteChar('T'); sysConsoleWriteChar('['); sysConsoleWriteInteger(chosenSpu, 0); sysConsoleWriteChar(']'); sysConsoleWriteChar(':'); sysConsoleWriteChar('>'); sysConsoleWriteChar(' '); sysConsoleWriteInteger((int) message, 1); sysConsoleWriteChar('\n'); pthread_mutex_unlock(&fakeTrapLock); // send back ACK message = ACK; if (spe_in_mbox_write(global_spu_data->spus[chosenSpu].ctx, &(message), 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { fprintf(stderr, "Error writing ack for console write message\n"); exit(1); } }
void handleFakeTrap (int chosenSpu) { unsigned int message; char * str; int i, length; spe_out_mbox_read(global_spu_data->spus[chosenSpu].ctx, &(message), 1); pthread_mutex_lock(&fakeTrapLock); sysConsoleWriteChar('F'); sysConsoleWriteChar('T'); sysConsoleWriteChar('['); sysConsoleWriteInteger(chosenSpu, 0); sysConsoleWriteChar(']'); sysConsoleWriteChar(':'); sysConsoleWriteChar('>'); sysConsoleWriteChar(' '); str = (char *) (global_spu_data->boot_record->fakeTrapStrs[message]); length = *((int *) (str - 4)); for (i=0; i<length; i++) { sysConsoleWriteChar(str[i]); } sysConsoleWriteChar('\n'); pthread_mutex_unlock(&fakeTrapLock); // send back ACK message = ACK; if (spe_in_mbox_write(global_spu_data->spus[chosenSpu].ctx, &(message), 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { fprintf(stderr, "Error writing ack for console write message\n"); exit(1); } }
extern "C" void runMigratedMethod(SpuThreadData * spu_data, int chosenSpu, int runMethodSignal) { unsigned int signalData, err; // signal spu to run method signalData = (unsigned int) runMethodSignal; if (spe_in_mbox_write(spu_data->spus[chosenSpu].ctx, &signalData, 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { perror("Failed while trying to signal method details to Cell SPU"); exit(1); } // check we get an ACK back if (spe_out_intr_mbox_read(spu_data->spus[chosenSpu].ctx, &signalData, 1, SPE_MBOX_ALL_BLOCKING) < 0) { perror("Failed reading SPU mailbox while awaiting SPU method invocation"); exit(1); } // if method run was not acked if (signalData != ACK) { // read error signal spe_out_mbox_read(spu_data->spus[chosenSpu].ctx, &err, 1); fprintf(stderr, "SPU did not ACK method run signal, signaled 0x%x, returned error no. 0x%x\n", signalData, err); exit(1); } }
int main (void) { pthread_t pts; spe_context_ptr_t ctx; unsigned int value; unsigned int pid; ctx = spe_context_create (0, NULL); pthread_create (&pts, NULL, &spe_thread, &ctx); /* Wait until the SPU thread is running. */ spe_out_intr_mbox_read (ctx, &value, 1, SPE_MBOX_ALL_BLOCKING); pid = fork (); if (pid == 0) { /* This is the child. Just exit immediately. */ exit (0); } else { /* This is the parent. Wait for the child to exit. */ waitpid (pid, NULL, 0); } /* Tell SPU to continue. */ spe_in_mbox_write (ctx, &value, 1, SPE_MBOX_ALL_BLOCKING); pthread_join (pts, NULL); spe_context_destroy (ctx); return 0; }
void internal_lessequal(long a, float b) { //printf("Inside internal add\n"); //b must be wrapped in a PyArrayObject PyArrayObject *scalar = (PyArrayObject*)_malloc_align(sizeof(PyArrayObject),7); scalar->blockData = (char**)_malloc_align(sizeof(char*),7); scalar->blockData[0] = (char*)_malloc_align(sizeof(float),7); ((float*)(scalar->blockData[0]))[0] = b; scalar->numberOfBlocks = 1; //Setting the Operation object Operation_t op1; op1.shaderSize = arraylessequal_arrayscalar_size; op1.EA_shader = arraylessequal_arrayscalar; op1.obj[0] = a; op1.obj[1] = scalar; op1.obj[2] = a; //printf("arraymultiply: %d\n",arraydivide); //printf("&arraymultiply: %d\n",&arraydivide); op1.num_SPES = speThreads; unsigned int i = 0; for(i = 0;i<speThreads;i++) { spe_pointer_addr[i][0] = &op1; } //printf("Adr of op1 sat. It is: %x\n",&op1); unsigned int state = 1; unsigned int y; for ( y = 0 ; y < speThreads ; y++ ) { //printf("Sending state to disp\n"); spe_in_mbox_write ( speData[y].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); //printf("TO THE DISP. THE SUM STATE: %d, has just been sent\n",&state); //printf("This is the actual value: %d\n",state); } //printf("ADD Waiting for the SPE's\n");//ALSO, check that the structure used is correct! // Waiting for SPEs! //printf( "Waiting for SPEs\n" ); unsigned int checked = 0; unsigned int r; while( checked < speThreads ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; //printf("Something read on the inbox\n"); } } //printf("Done waiting on threads to finish in LESSEQUAL\n"); }
static void ask_for_results(spe_context_ptr_t *ctxs) { int j; for (j = 0; j < SPU_THREADS; j++) spe_in_mbox_write(ctxs[j], (void *) &j, 1, SPE_MBOX_ANY_NONBLOCKING); printf("PPU asked for results from all the spu\n"); }
/* Register the event handlers for each context */ void waitForSpus(SpuThreadData * spu_data) { int i, no_spus; pid_t pid; no_spus = spu_data->no_spu_threads; pid = getpid(); // used to order reorder spu's by physical id unsigned int phys_ids [no_spus]; for (i=0; i<no_spus; i++) { unsigned int message_data [2]; unsigned long long spu_id; if (spe_out_intr_mbox_read(spu_data->spus[i].ctx, message_data, 2, SPE_MBOX_ALL_BLOCKING) < 0) { perror("Failed reading SPU mailbox while awaiting SPU boot"); exit(1); } spu_id = ((unsigned long long)message_data[0]) << 32 | message_data[1]; // find out the physical spu number for each thread phys_ids[i] = getPhysID(spu_id, (unsigned long long)spu_data->gang, pid); spu_data->spus[i].phys_id = phys_ids[i]; if (spe_in_mbox_write(spu_data->spus[i].ctx, &(phys_ids[i]), 1, SPE_MBOX_ALL_BLOCKING) < 0) { perror("Failed writing phys_id to SPU mailbox while SPU was booting"); exit(1); } } // order ctxs and threads by phys id SpuData * new_spus = (SpuData *) malloc(sizeof(SpuData) * no_spus); for (i=0; i<no_spus; i++) { int j, current_idx; unsigned int current; current = 0xefffffff; current_idx = 0; for (j=0; j<no_spus; j++) { if (phys_ids[j] < current) { current = phys_ids[j]; current_idx = j; } } memcpy(&(new_spus[i]), &(spu_data->spus[current_idx]), sizeof(SpuData)); phys_ids[current_idx] = 0xefffffff; } free(spu_data->spus); spu_data->spus = new_spus; }
initDisp( unsigned int numspes ) { // Get the number of available SPEs speThreads = spe_cpu_info_get(SPE_COUNT_USABLE_SPES, -1); // Clamp to the defined number of SPEs used if ( speThreads > MAX_SPU_NUM ) { speThreads = MAX_SPU_NUM; } if( speThreads > numspes ) { speThreads = numspes; } //printf("InitDist. speThreads is: %d\n",speThreads); unsigned int i; unsigned int temp; // Get dispatcher //printf("Getting the dispatcher\n"); //spe_program_handle_t *dispatcher = spe_image_open( "/home/jens/numpycbe_dispatcher" ); spe_program_handle_t *dispatcher = spe_image_open( "./../../../../numpycbe_dispatcher" ); //printf("After getting the dispatcher\n"); // Initialize threads for( i = 0 ; i < speThreads ; i++ ) { CreateSPEThread( &speData[i], dispatcher, &spe_pointer_addr[i] ); // Sending the SPE its id //printf("spe_write MULTIARRAYMODULE Sending id to SPE %d.\n",i); spe_in_mbox_write ( speData[i].spe_ctx, &i, 1, SPE_MBOX_ALL_BLOCKING ); // Sending the SPE its seed. This should be something like time instead of id? //printf("spe_write MULTIARRAYMODULE Sending seed to SPE %d.\n",i); spe_in_mbox_write ( speData[i].spe_ctx, &i, 1, SPE_MBOX_ALL_BLOCKING ); } //printf("speData[i].spe_ctx is : %d\n",speData[i].spe_ctx); //spe_in_mbox_write ( (void*)temp, &i, 1, SPE_MBOX_ALL_BLOCKING ); return 0; }
void sws_yuvscaler_destroy(yuvscaler_t* arg) { unsigned int message=STOP; struct yuvscaler_s * arg_ptr; arg_ptr=(struct yuvscaler_s *) arg; spe_in_mbox_write(arg_ptr->ctx,&message,1,SPE_MBOX_ALL_BLOCKING); pthread_join(arg_ptr->pts,NULL); spe_context_destroy(arg_ptr->ctx); }
void internal_div(long a, long b) { //printf("Inside internal add\n"); //Setting the Operation object Operation_t op1; op1.shaderSize = arraydivide_size; op1.EA_shader = arraydivide; op1.obj[0] = a; op1.obj[1] = b; op1.obj[2] = a; //printf("arraymultiply: %d\n",arraydivide); //printf("&arraymultiply: %d\n",&arraydivide); op1.num_SPES = speThreads; unsigned int i = 0; for(i = 0;i<speThreads;i++) { spe_pointer_addr[i][0] = &op1; } //printf("Adr of op1 sat. It is: %x\n",&op1); unsigned int state = 1; unsigned int y; for ( y = 0 ; y < speThreads ; y++ ) { //printf("Sending state to disp\n"); spe_in_mbox_write ( speData[y].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); //printf("TO THE DISP. THE SUM STATE: %d, has just been sent\n",&state); //printf("This is the actual value: %d\n",state); } //printf("ADD Waiting for the SPE's\n");//ALSO, check that the structure used is correct! // Waiting for SPEs! //printf( "Waiting for SPEs\n" ); unsigned int checked = 0; unsigned int r; while( checked < speThreads ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; //printf("Something read on the inbox\n"); } } //printf("Done waiting on threads to finish in DIV\n"); }
int SPE_SendMsg(_THIS, spu_data_t * spe_data, unsigned int msg) { deprintf(2, "[PS3->SPU] Sending message %u to %s\n", msg, spe_data->program_name); unsigned int spe_in_mbox_msgs[1]; spe_in_mbox_msgs[0] = msg; int in_mbox_write = spe_in_mbox_write(spe_data->ctx, spe_in_mbox_msgs, 1, SPE_MBOX_ALL_BLOCKING); if (1 > in_mbox_write) { deprintf(2, "[PS3->SPU] No message could be written to %s\n", spe_data->program_name); SDL_SetError("[PS3->SPU] No message could be written"); return -1; } return 0; }
void handleConsoleWrite (int chosenSpu) { unsigned int char_val, ack; if (spe_out_mbox_read(global_spu_data->spus[chosenSpu].ctx, &(char_val), 1) < 0) { fprintf(stderr, "Error reading console write message\n"); exit(1); } sysConsoleWriteChar(char_val); // send back ACK ack = ACK; if (spe_in_mbox_write(global_spu_data->spus[chosenSpu].ctx, &(ack), 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { fprintf(stderr, "Error writing ack for console write message\n"); exit(1); } }
void handleConsoleLongWrite(int chosenSpu, int cmdSignal) { unsigned int long_val[2], ack; if (spe_out_mbox_read(global_spu_data->spus[chosenSpu].ctx, long_val, 2) < 0) { fprintf(stderr, "Error reading console write int message\n"); exit(1); } sysConsoleWriteLong(*((long long *)long_val), cmdSignal - CONSOLE_WRITE_INT); // send back ACK ack = ACK; if (spe_in_mbox_write(global_spu_data->spus[chosenSpu].ctx, &(ack), 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { fprintf(stderr, "Error writing ack for console write int message\n"); exit(1); } }
void handleConsoleDoubleWrite(int chosenSpu) { unsigned int double_val[3], ack; if (spe_out_mbox_read(global_spu_data->spus[chosenSpu].ctx, double_val, 3) < 0) { fprintf(stderr, "Error reading console write int message\n"); exit(1); } sysConsoleWriteDouble(*((double *)double_val), (int) double_val[2]); // send back ACK ack = ACK; if (spe_in_mbox_write(global_spu_data->spus[chosenSpu].ctx, &(ack), 1, SPE_MBOX_ANY_NONBLOCKING) < 0) { fprintf(stderr, "Error writing ack for console write int message\n"); exit(1); } }
double SSCAL( PyArrayObject *pyobj1, PyArrayObject *pyscalar1, unsigned int shadersize, unsigned int *shader ) { Tic(); Operation_t op1; op1.shaderSize = shadersize; op1.EA_shader = shader; op1.obj[0] = pyobj1; op1.scalar[0] = pyscalar1; op1.num_SPES = speThreads; unsigned int state = 1, r; unsigned int i; //printf( "Sending states to SPEs\n" ); for ( i = 0 ; i < speThreads ; i++ ) { spe_pointer_addr[i][0] = (unsigned int)&op1; spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! //printf( "Waiting for SPEs\n" ); unsigned int checked = 0; while( checked < speThreads ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } double time = Toc_d(); PrintTicToc( "Finished at ", Toc() ); for( i = 0 ; i < 3 ; i++ ) { printf( "%u=%f\n", i, ((float*)pyobj1->blockData[0])[i] ); } return time; }
/* * Run with three arrays, no run */ void run30nr( PyArrayObject *pyobj1, PyArrayObject *pyobj2, PyArrayObject *pyobj3, unsigned int shadersize, unsigned int *shader, unsigned int shaderindex ) { Operation_t op1; op1.shaderSize = shadersize; op1.EA_shader = shader; // Determining the number of SPEs //op1.num_SPES = _GetNumberOfSPES( pyobj1->numberOfBlocks ); op1.num_SPES = 1; op1.obj[0] = pyobj1; op1.obj[1] = pyobj2; op1.obj[2] = pyobj3; unsigned int checked = 0; unsigned int state = 200 + shaderindex, r; unsigned int i; // printf( "HERE %u!\n", state ); // printf( "SIZE=%u, ADDR=%#x\n", op1.shaderSize, op1.EA_shader ); for ( i = 0 ; i < op1.num_SPES ; i++ ) { //printf( "-->%u\n",i ); spe_pointer_addr[i][shaderindex] = (unsigned int)&op1; spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! checked = 0; while( checked < op1.num_SPES ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } }
extern "C" int sysVirtualSubArchProcessorBind(VM_Address procObj, int procID) { unsigned int signal[2]; // TODO - do some checking here SpuData spu = global_spu_data->spus[procID]; signal[0] = SET_PROCESSOR_REG; signal[1] = (unsigned int) procObj; // tell spu runtime its processor object if (spe_in_mbox_write(spu.ctx, signal, 2, SPE_MBOX_ANY_NONBLOCKING) < 0) { perror("Failed while trying to signal method details to Cell SPU"); exit(1); } // wait for ACK from SPU if (spe_out_intr_mbox_read(spu.ctx, signal, 1, SPE_MBOX_ALL_BLOCKING) < 0) { perror("Faied reading SPU mailbox while awaiting SPU boot"); exit(1); } if (signal[0] != ACK) { spe_out_mbox_read(spu.ctx, signal, 1); fprintf(stderr, "SPU did not ACK setProcessor, returned error no. 0x%x\n", signal[0]); exit(1); } return 0; }
/* * Run with two arrays and two scalars */ void run22( PyArrayObject *A, PyArrayObject *x, PyArrayObject *alpha, PyArrayObject *j, unsigned int shadersize, unsigned int *shader ) { Operation_t op1; op1.shaderSize = shadersize; op1.EA_shader = shader; // Determining the number of SPEs op1.num_SPES = _GetNumberOfSPES( A->numberOfBlocks ); op1.obj[0] = A; op1.obj[1] = x; op1.scalar[0] = alpha; op1.scalar[1] = j; unsigned int checked = 0; unsigned int state = 0, r; unsigned int i; for ( i = 0 ; i < op1.num_SPES ; i++ ) { spe_pointer_addr[i][0] = (unsigned int)&op1; spe_in_mbox_write ( speData[i].spe_ctx, &state, 1, SPE_MBOX_ALL_BLOCKING ); } // Waiting for SPEs! checked = 0; while( checked < op1.num_SPES ) { if ( spe_out_mbox_status( speData[checked].spe_ctx ) ) { spe_out_mbox_read( speData[checked].spe_ctx, &r, 1 ); checked++; } } }
/** * Write a 1-word message to the given SPE mailbox. */ void send_mbox_message(spe_context_ptr_t ctx, unsigned int msg) { spe_in_mbox_write(ctx, &msg, 1, SPE_MBOX_ALL_BLOCKING); }
void spe_set_status(int id, uint32_t status) { threads[id].status = status; spe_in_mbox_write(threads[id].speid, (uint32_t*)(&threads[id].status), 1, SPE_MBOX_ANY_NONBLOCKING); }
int main(int argc, char** argv) { double begin; double end; int errnum; size_t nthread = P; size_t i; size_t nvertex; unsigned int x; // sent to each SPU int code; // status; unsigned int reply; // from SPU arg_t data[nthread]; param_t param[nthread] A16; argc = argc; // to silence gcc... progname = argv[0]; nvertex = atoi(argv[2]); printf("nthread = %zu\n", nthread); printf("nvertex = %zu\n", nvertex); printf("ctx = %zu\n", sizeof(param_t)); printf("arg = %zu\n", sizeof(arg_t)); begin = sec(); for (i = 0; i < nthread; ++i) { param[i].proc = i; param[i].nvertex = nvertex; if ((data[i].ctx = spe_context_create (0, NULL)) == NULL) { perror ("Failed creating context"); exit(1); } if (spe_program_load (data[i].ctx, &dataflow)) { perror ("Failed loading program"); exit(1); } data[i].arg = ¶m[i]; printf("i=%d param=%p\n", i, data[i].arg); if (pthread_create (&data[i].pthread, NULL, work, &data[i])) { perror ("Failed creating thread"); exit(1); } } // send some data to each SPU and wait for a reply. x = 42; for (i = 0; i < nthread; ++i) { reply = 0; code = spe_out_mbox_read(data[i].ctx, &reply, 1); printf("spu-%d reply-0: %u\tcode: %d\n",i, reply, code); code = spe_in_mbox_write(data[i].ctx, &x, 1, 1); code = spe_out_mbox_read(data[i].ctx, &reply, 1); printf("spu-%d reply-1: %u\tcode: %d\n",i, reply, code); code = spe_out_mbox_read(data[i].ctx, &reply, 1); printf("spu-%d reply-2: %u\tcode: %d\n",i, reply, code); } end = sec(); printf("%1.3lf s\n", end-begin); for (i = 0; i < nthread; ++i) { printf("joining with PPU pthread %zu...\n", i); errnum = pthread_join(data[i].pthread, NULL); if (errnum != 0) syserror(errnum, "pthread_join failed"); if (spe_context_destroy (data[i].ctx) != 0) { perror("Failed destroying context"); exit(1); } } return 0; }
///send messages to SPUs void SpuLibspe2Support::sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1) { spe_context_ptr_t context; switch (uiCommand) { case CMD_SAMPLE_TASK_COMMAND: { //get taskdescription SpuSampleTaskDesc* taskDesc = (SpuSampleTaskDesc*) uiArgument0; btAssert(taskDesc->m_taskId<m_activeSpuStatus.size()); //get status of SPU on which task should run btSpuStatus& spuStatus = m_activeSpuStatus[taskDesc->m_taskId]; //set data for spuStatus spuStatus.m_commandId = uiCommand; spuStatus.m_status = Spu_Status_Occupied; //set SPU as "occupied" spuStatus.m_taskDesc.p = taskDesc; //get context context = data[taskDesc->m_taskId].context; taskDesc->m_mainMemoryPtr = reinterpret_cast<uint64_t> (spuStatus.m_lsMemory.p); break; } case CMD_GATHER_AND_PROCESS_PAIRLIST: { //get taskdescription SpuGatherAndProcessPairsTaskDesc* taskDesc = (SpuGatherAndProcessPairsTaskDesc*) uiArgument0; btAssert(taskDesc->taskId<m_activeSpuStatus.size()); //get status of SPU on which task should run btSpuStatus& spuStatus = m_activeSpuStatus[taskDesc->taskId]; //set data for spuStatus spuStatus.m_commandId = uiCommand; spuStatus.m_status = Spu_Status_Occupied; //set SPU as "occupied" spuStatus.m_taskDesc.p = taskDesc; //get context context = data[taskDesc->taskId].context; taskDesc->m_lsMemory = (CollisionTask_LocalStoreMemory*)spuStatus.m_lsMemory.p; break; } default: { ///not implemented btAssert(0); } }; //write taskdescription in mailbox unsigned int event = Spu_Mailbox_Event_Task; spe_in_mbox_write(context, &event, 1, SPE_MBOX_ANY_NONBLOCKING); }