Serial/parallel task iterator version of the VM engine
| 243 | |
| 244 | // Serial/parallel task iterator version of the VM engine |
| 245 | int vm_engine_iter_task(NpyIter *iter, |
| 246 | const NumExprObject *params, int tid, |
| 247 | int *pc_error, char **errorMessage) |
| 248 | { |
| 249 | NpyIter_IterNextFunc *iterNext; |
| 250 | npy_intp task_size, *sizePtr; |
| 251 | char **iterDataPtr; |
| 252 | npy_intp *iterStrides; |
| 253 | |
| 254 | iterNext = NpyIter_GetIterNext(iter, errorMessage); |
| 255 | if (iterNext == NULL) { |
| 256 | return -1; |
| 257 | } |
| 258 | |
| 259 | sizePtr = NpyIter_GetInnerLoopSizePtr(iter); |
| 260 | iterDataPtr = NpyIter_GetDataPtrArray(iter); |
| 261 | iterStrides = NpyIter_GetInnerStrideArray(iter); |
| 262 | |
| 263 | // DEBUG |
| 264 | // printf( "DEBUG vm_enginer_iter_task\n" ); |
| 265 | // for( int I = 0; I < params->program_len; I++ ) { |
| 266 | // printf( "program[%d]:: r:%d a1:%d a1:%d a2:%d a3:%d \n", I, |
| 267 | // (int)params->program[I].op, (int)params->program[I].ret, (int)params->program[I].arg1, |
| 268 | // (int)params->program[I].arg2, (int)params->program[I].arg3 ); |
| 269 | // } |
| 270 | // for( int I = 0; I < params->n_reg; I++ ) { |
| 271 | // printf( "regs[%d]:: kind:%d, mem:%p, \n", I, params->registers[I].kind, params->registers[I].mem ); |
| 272 | // } |
| 273 | // printf( "params: %p, n_reg: %d, iter: %p\n", params, params->n_reg, iter ); |
| 274 | // for( int I = 0; I < params->n_reg; I++ ) { |
| 275 | // int ac = 0; |
| 276 | // if( params->registers[I].kind & (KIND_ARRAY | KIND_RETURN) ) { |
| 277 | // printf( "iterDataPtr[%d]:: %p, iterStrides[%d]:: %ld, sizePtr:: %ld \n", |
| 278 | // I, iterDataPtr[ac], I, (void *)iterStrides[ac], *sizePtr ); |
| 279 | // ac++; |
| 280 | // } |
| 281 | // } |
| 282 | // printf("END DEBUG\n"); |
| 283 | |
| 284 | // First do all the blocks with a compile-time fixed size. This makes a |
| 285 | // big difference (30-50% on some tests). |
| 286 | // TODO: this can be replaced in the generator with a fixed size in |
| 287 | // _bytes_ instead of _elements_ |
| 288 | |
| 289 | task_size = *sizePtr; |
| 290 | // Success, with auto-vectorization it doesn't need to be a fixed size, |
| 291 | // compared to unrolling loops. Looks like we can cut-down the number of |
| 292 | // includes which will shrink the machine code. |
| 293 | while( task_size > 0 ) { |
| 294 | #define REDUCTION_INNER_LOOP |
| 295 | #include "interp_body_GENERATED.cpp" |
| 296 | #undef REDUCTION_INNER_LOOP |
| 297 | iterNext(iter); |
| 298 | task_size = *sizePtr; |
| 299 | } |
| 300 | |
| 301 | return 0; |
| 302 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…