<commit_before>/* 
 * File:   SubsamplingLayer.cpp
 * Author: janvojt
 * 
 * Created on May 16, 2015, 11:38 PM
 */

#include "SubsamplingLayer.h"

#include <cstdlib>
#include <algorithm>
#include <sstream>
#include "../../common.h"
#include "../LayerFactory.h"

#include "../../log/LoggerFactory.h"
#include "log4cpp/Category.hh"

SubsamplingLayer::SubsamplingLayer() {
}

SubsamplingLayer::SubsamplingLayer(const SubsamplingLayer& orig) {
}

SubsamplingLayer::~SubsamplingLayer() {
}

void SubsamplingLayer::setup(string confString) {

    processConfString(confString);
    
    if (previousLayer == NULL) {
        // this is an input layer
        inputFeatureWidth = conf.windowWidth;
        inputFeatureHeight = conf.windowHeight;
        featureWidth = conf.windowWidth;
        featureHeight = conf.windowHeight;
        featuresCount = 1;
        this->outputsCount = conf.windowWidth * conf.windowHeight;
        this->weightsCount = 0;
    } else {
        ConvolutionalLayer *convLayer = (ConvolutionalLayer*) previousLayer;
        featuresCount = convLayer->getOutputFeatures();
        inputFeatureWidth = convLayer->getOutputWidth();
        inputFeatureHeight = convLayer->getOutputHeight();

        featureWidth = (inputFeatureWidth + conf.windowWidth - 1)  / conf.windowWidth; // round up
        featureHeight = (inputFeatureHeight + conf.windowHeight - 1) / conf.windowHeight; // round up
        this->outputsCount = featureWidth * featureHeight * featuresCount;

        // subsampling layer does not need any weights
        // but uses a trainable parameter for each feature map
        // and optionally bias for each feature map
        this->weightsCount = conf.useBias ? featuresCount*2 : featuresCount;
        
        maxIndices = new int[outputsCount];
    }
}

void SubsamplingLayer::forwardCpu() {
    
    data_t *inputs = this->previousLayer->getOutputs();
    int wfeatureWidth = inputFeatureWidth / conf.windowWidth;
    int wfeatureHeight = inputFeatureHeight / conf.windowHeight;
    
    // clear output
    std::fill_n(outputs, outputsCount, 0);
    
    // loop through destination neuron
    for (int f = 0; f < featuresCount; f++) {
        int dstFeatureIdx = f * wfeatureWidth * wfeatureHeight;
        int srcFeatureIdx = f * inputFeatureWidth * inputFeatureHeight;
        
        for (int i = 0; i < wfeatureHeight; i++) { // row index
            int rowIdx = dstFeatureIdx + i * wfeatureWidth;
            
            for (int j = 0; j < wfeatureWidth; j++) { // column index
                int dstNeuronIdx = rowIdx + j;
                // set maximum to the lowest value possible
                outputs[dstNeuronIdx] = -1;
                
                // loop through source neurons
                for (int k = 0; k < conf.windowHeight; k++) { // row index
                    for (int l = 0; l < conf.windowWidth; l++) { // column index

                        int srcNeuronIdx =  srcFeatureIdx + (k + i*conf.windowHeight) * inputFeatureWidth + (l + j*conf.windowWidth);
                        if (inputs[srcNeuronIdx] > outputs[dstNeuronIdx]) {
                            outputs[dstNeuronIdx] = inputs[srcNeuronIdx];
                            maxIndices[dstNeuronIdx] = srcNeuronIdx;
                        }
                    }
                }
            } // end loop through destination neuron
        }
    }

//    netConf->activationFnc(outputs, outputs, outputsCount);
    <commit_msg>Fixed segfault in Subsampling layer.<commit_after>/* 
 * File:   SubsamplingLayer.cpp
 * Author: janvojt
 * 
 * Created on May 16, 2015, 11:38 PM
 */

#include "SubsamplingLayer.h"

#include <cstdlib>
#include <algorithm>
#include <sstream>
#include <float.h>
#include "../../common.h"
#include "../LayerFactory.h"

#include "../../log/LoggerFactory.h"
#include "log4cpp/Category.hh"

SubsamplingLayer::SubsamplingLayer() {
}

SubsamplingLayer::SubsamplingLayer(const SubsamplingLayer& orig) {
}

SubsamplingLayer::~SubsamplingLayer() {
}

void SubsamplingLayer::setup(string confString) {

    processConfString(confString);
    
    if (previousLayer == NULL) {
        // this is an input layer
        inputFeatureWidth = conf.windowWidth;
        inputFeatureHeight = conf.windowHeight;
        featureWidth = conf.windowWidth;
        featureHeight = conf.windowHeight;
        featuresCount = 1;
        this->outputsCount = conf.windowWidth * conf.windowHeight;
        this->weightsCount = 0;
    } else {
        ConvolutionalLayer *convLayer = (ConvolutionalLayer*) previousLayer;
        featuresCount = convLayer->getOutputFeatures();
        inputFeatureWidth = convLayer->getOutputWidth();
        inputFeatureHeight = convLayer->getOutputHeight();

        featureWidth = (inputFeatureWidth + conf.windowWidth - 1)  / conf.windowWidth; // round up
        featureHeight = (inputFeatureHeight + conf.windowHeight - 1) / conf.windowHeight; // round up
        this->outputsCount = featureWidth * featureHeight * featuresCount;

        // subsampling layer does not need any weights
        // but uses a trainable parameter for each feature map
        // and optionally bias for each feature map
        this->weightsCount = conf.useBias ? featuresCount*2 : featuresCount;
        
        maxIndices = new int[outputsCount];
    }
}

void SubsamplingLayer::forwardCpu() {
    
    data_t *inputs = this->previousLayer->getOutputs();
    int wfeatureWidth = inputFeatureWidth / conf.windowWidth;
    int wfeatureHeight = inputFeatureHeight / conf.windowHeight;
    
    // clear output
    std::fill_n(outputs, outputsCount, 0);
    
    // loop through destination neuron
    for (int f = 0; f < featuresCount; f++) {
        int dstFeatureIdx = f * wfeatureWidth * wfeatureHeight;
        int srcFeatureIdx = f * inputFeatureWidth * inputFeatureHeight;
        
        for (int i = 0; i < wfeatureHeight; i++) { // row index
            int rowIdx = dstFeatureIdx + i * wfeatureWidth;
            
            for (int j = 0; j < wfeatureWidth; j++) { // column index
                int dstNeuronIdx = rowIdx + j;
                // set maximum to the lowest value possible
                outputs[dstNeuronIdx] = -FLT_MAX;
                
                // loop through source neurons
                for (int k = 0; k < conf.windowHeight; k++) { // row index
                    for (int l = 0; l < conf.windowWidth; l++) { // column index

                        int srcNeuronIdx =  srcFeatureIdx + (k + i*conf.windowHeight) * inputFeatureWidth + (l + j*conf.windowWidth);
                        if (inputs[srcNeuronIdx] > outputs[dstNeuronIdx]) {
                            outputs[dstNeuronIdx] = inputs[srcNeuronIdx];
                            maxIndices[dstNeuronIdx] = srcNeuronIdx;
                        }
                    }
                }
            } // end loop through destination neuron
        }
    }

//    netConf->activationFnc(outputs, outputs, outputsCount);
    
{'fraction_non_alphanumeric': 0.10340389016018306, 'fraction_numerical': 0.006435926773455378, 'mean_word_length': 2.2270419935394554, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '355863', 'n_tokens_mistral': 1982, 'n_tokens_neox': 1863, 'n_words': 484}