- Timestamp:
- Jan 16, 2019, 11:41:05 PM (6 years ago)
- Branches:
- feature/crepe_org
- Children:
- 591f077
- Parents:
- ec3f4d63
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ai/conv2d.c
rec3f4d63 r4d6a228 45 45 uint_t output_shape[3]; // shape of output 46 46 uint_t padding_start[2]; // {top, left} padding 47 48 #if defined(HAVE_BLAS) 49 aubio_tensor_t *padded_input; 50 #endif 47 51 }; 48 52 … … 85 89 if (c->bias) 86 90 del_fvec(c->bias); 91 #if defined(HAVE_BLAS) 92 if (c->padded_input) 93 del_aubio_tensor(c->padded_input); 94 #endif 87 95 AUBIO_FREE(c); 88 96 } … … 110 118 uint_t output_shape[3] = {0, 0, c->n_filters}; 111 119 uint_t padding_start[2] = {0, 0}; 120 // total amount of padding 121 uint_t padding_shape[2] = {0, 0}; 112 122 113 123 // check input parameters … … 128 138 / (smpl_t)c->stride_shape[1]); 129 139 130 uint_t padding_shape[2]; // total amount of padding131 140 padding_shape[0] = (output_shape[0] - 1) * c->stride_shape[0] 132 141 + c->kernel_shape[0] - input_tensor->shape[0]; … … 180 189 shape[1] = output_shape[1]; 181 190 shape[2] = output_shape[2]; 191 192 193 #if defined(HAVE_BLAS) 194 // im2col padding 195 padding_shape[0] = output_shape[0] * output_shape[1]; 196 padding_shape[1] = c->kernel_shape[0] * c->kernel_shape[1] 197 * input_tensor->shape[2]; 198 c->padded_input = new_aubio_tensor(2, padding_shape); 199 if (!c-> padded_input) { 200 AUBIO_MSG("conv2d: failed creating padded_input with shape (%d, %d, %d)\n", 201 padding_shape); 202 return AUBIO_FAIL; 203 } 204 #endif 182 205 183 206 aubio_conv2d_debug(c, input_tensor); … … 232 255 } 233 256 257 #if !defined(HAVE_BLAS) 234 258 void aubio_conv2d_do(aubio_conv2d_t *c, aubio_tensor_t *input_tensor, 235 259 aubio_tensor_t *activations) … … 301 325 } 302 326 327 #else /* HAVE_BLAS */ 328 329 void aubio_conv2d_copy_to_padded(aubio_conv2d_t *o, 330 aubio_tensor_t *input_tensor, aubio_tensor_t *padded_input) 331 { 332 // naive implementation of im2col 333 uint_t i, j, k, l, m; 334 uint_t stride_4 = o->kernel->shape[2]; 335 uint_t stride_3 = o->kernel->shape[1] * stride_4; 336 uint_t stride_2 = o->kernel->shape[0] * stride_3; 337 uint_t stride_1 = o->output_shape[1] * stride_2; 338 uint_t stride_in_2 = input_tensor->shape[2]; 339 uint_t stride_in_1 = input_tensor->shape[1] * stride_in_2; 340 341 AUBIO_ASSERT(padded_input->size == 342 o->output_shape[0] * o->output_shape[1] 343 * o->kernel_shape[0] * o->kernel_shape[1] 344 * input_tensor->shape[2]); 345 AUBIO_ASSERT(input_tensor->shape[2] == o->kernel->shape[2]); 346 347 for (i = 0; i < o->output_shape[0]; i++) 348 { 349 for (j = 0; j < o->output_shape[1]; j++) 350 { 351 for (k = 0; k < o->kernel->shape[0]; k++) 352 { 353 for (l = 0; l < o->kernel->shape[1]; l++) 354 { 355 for (m = 0; m < o->kernel->shape[2]; m++) 356 { 357 uint_t read_i = i * o->stride_shape[0] + k; 358 uint_t read_j = j * o->stride_shape[1] + l; 359 if (read_i < o->padding_start[0]) 360 continue; 361 else if (read_i - o->padding_start[0] >= input_tensor->shape[0]) 362 continue; 363 if (read_j < o->padding_start[1]) 364 continue; 365 else if (read_j - o->padding_start[1] >= input_tensor->shape[1]) 366 continue; 367 368 sint_t idx = 369 ((read_i - o->padding_start[0])) * stride_in_1 370 + ((read_j - o->padding_start[1])) * stride_in_2 371 + m; 372 padded_input->buffer[i * stride_1 373 + j * stride_2 374 + k * stride_3 375 + l * stride_4 376 + m] 377 = input_tensor->buffer[idx]; 378 } 379 } 380 } 381 } 382 } 383 } 384 385 void aubio_conv2d_do(aubio_conv2d_t *o, aubio_tensor_t *input_tensor, 386 aubio_tensor_t *activations) 387 { 388 uint_t i, j; 389 smpl_t bias; 390 aubio_tensor_t *padded_input = o->padded_input; 391 aubio_tensor_t *kernel = o->kernel; 392 393 AUBIO_ASSERT(o && input_tensor && activations); 394 // check we have the correct output activation sizes 395 if (aubio_conv2d_check_output_shape(o, input_tensor, activations)) 396 { 397 AUBIO_ERR("conv2d: check_output_shape failed\n"); 398 return; 399 } 400 401 uint_t M = padded_input->shape[0]; 402 uint_t K = padded_input->size/padded_input->shape[0]; 403 uint_t N = kernel->size / K; 404 405 // check sizes 406 AUBIO_ASSERT(M * K == padded_input->size); 407 AUBIO_ASSERT(N * K == kernel->size); 408 AUBIO_ASSERT(M * N == activations->size); 409 410 // copy input to im2col sliding window version 411 aubio_conv2d_copy_to_padded(o, input_tensor, padded_input); 412 413 aubio_cblas__gemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 414 M, // M 415 N, // N 416 K, // K 417 1.F, // alpha 418 padded_input->buffer, // M x K matrix 419 K, // K (2nd dim of A) 420 kernel->buffer, // K x N matrix 421 N, // N 422 0.F, // beta 423 activations->buffer, // M x N matrix 424 N); // N (2nd dim of C) 425 426 427 // apply bias 428 for (i = 0; i < activations->shape[2]; i++) { 429 bias = o->bias->data[i]; 430 for (j = 0; j < activations->shape[0] * activations->shape[1]; j++) 431 { 432 activations->buffer[j * activations->shape[2] + i] += bias; 433 } 434 } 435 } 436 #endif 437 303 438 void aubio_conv2d_do_backwards(aubio_conv2d_t *c, 304 439 /*aubio_tensor_t *old_gradients,*/
Note: See TracChangeset
for help on using the changeset viewer.