packages feed

grenade-0.1.0: cbits/im2col.c

#include "im2col.h"

void im2col_cpu(const double* data_im, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int stride_h, const int stride_w,
    double* data_col) {

  const int channel_size = height * width;

  for (int fitting_height = 0; fitting_height <= (height - kernel_h); fitting_height += stride_h) {
    for (int fitting_width = 0; fitting_width <= (width - kernel_w); fitting_width += stride_w) {
      for (int channel = 0; channel < channels; channel++) {
        for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) {
          for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
            int input_row = fitting_height + kernel_row;
            int input_col = fitting_width + kernel_col;
            *(data_col++) = data_im[input_row * width + input_col + channel_size * channel];
          }
        }
      }
    }
  }
}

void col2im_cpu(const double* data_col, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int stride_h, const int stride_w,
    double* data_im) {

  memset(data_im, 0, height * width * channels * sizeof(double));

  const int channel_size = height * width;

  for (int fitting_height = 0; fitting_height <= (height - kernel_h); fitting_height += stride_h) {
    for (int fitting_width = 0; fitting_width <= (width - kernel_w); fitting_width += stride_w) {
      for (int channel = 0; channel < channels; channel++) {
        for (int kernel_row = 0; kernel_row < kernel_h; kernel_row++) {
          for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
            int input_row = fitting_height + kernel_row;
            int input_col = fitting_width + kernel_col;
            data_im[input_row * width + input_col + channel_size * channel] += *(data_col++);
          }
        }
      }
    }
  }
}

inline double max ( double a, double b ) { return a > b ? a : b; }

void pool_forwards_cpu(const double* data_im, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int stride_h, const int stride_w,
    double* data_pooled) {

  const int channel_size = height * width;

  for (int channel = 0; channel < channels; channel++) {
    for (int fitting_height = 0; fitting_height <= (height - kernel_h); fitting_height += stride_h) {
      for (int fitting_width = 0; fitting_width <= (width - kernel_w); fitting_width += stride_w) {
        // Start with the value in 0,0
        int    max_index = fitting_height * width + fitting_width + channel_size * channel;
        double max_value = data_im[max_index];
        // Initial row, skipping the corner we've done
        for (int kernel_col = 1; kernel_col < kernel_w; kernel_col++) {
          int    input_row  = fitting_height;
          int    input_col  = fitting_width + kernel_col;
          int    data_index = input_row * width + input_col + channel_size * channel;
          double data_value = data_im[data_index];
          max_value = max ( max_value, data_value );
        }
        // The remaining rows
        for (int kernel_row = 1; kernel_row < kernel_h; kernel_row++) {
          for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
            int    input_row = fitting_height + kernel_row;
            int    input_col = fitting_width + kernel_col;
            int    data_index = input_row * width + input_col + channel_size * channel;
            double data_value = data_im[data_index];
            max_value = max ( max_value, data_value );
          }
        }
        *(data_pooled++) = max_value;
      }
    }
  }
}

void pool_backwards_cpu(const double* data_im, const double* data_pooled,
    const int channels, const int height, const int width, const int kernel_h,
    const int kernel_w, const int stride_h, const int stride_w,
    double* data_backgrad ) {

  memset(data_backgrad, 0, height * width * channels * sizeof(double));

  const int channel_size = height * width;

  for (int channel = 0; channel < channels; channel++) {
    for (int fitting_height = 0; fitting_height <= (height - kernel_h); fitting_height += stride_h) {
      for (int fitting_width = 0; fitting_width <= (width - kernel_w); fitting_width += stride_w) {
        int    max_index = fitting_height * width + fitting_width + channel_size * channel;
        double max_value = data_im[max_index];
        for (int kernel_col = 1; kernel_col < kernel_w; kernel_col++) {
          int    input_row  = fitting_height;
          int    input_col  = fitting_width + kernel_col;
          int    data_index = input_row * width + input_col + channel_size * channel;
          double data_value = data_im[data_index];
          if ( data_value > max_value )  {
              max_index = data_index;
              max_value = data_value;
          }
        }
        for (int kernel_row = 1; kernel_row < kernel_h; kernel_row++) {
          for (int kernel_col = 0; kernel_col < kernel_w; kernel_col++) {
            int    input_row = fitting_height + kernel_row;
            int    input_col = fitting_width + kernel_col;
            int    data_index = input_row * width + input_col + channel_size * channel;
            double data_value = data_im[data_index];
            if ( data_value > max_value )  {
              max_index = data_index;
              max_value = data_value;
            }
          }
        }
        data_backgrad[max_index] += *(data_pooled++);
      }
    }
  }
}