/******************************************************************************/ /*! * \file timlCNNProfile.c */ /* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ /******************************************************************************* * * INCLUDES * ******************************************************************************/ #include "../api/timl.h" /******************************************************************************/ /*! * \ingroup cnn * \brief Profile the CNN with both timing and memory allocation * \param[in] cnn CNN * \param[in] data Input data batch pointer * \param[in] dim Data dimension * \param[in] batchSize Data batch size * \param[in] label Label ptr * \param[in] iter Iterations * \return Error code */ /******************************************************************************/ int timlCNNProfile(timlConvNeuralNetwork *cnn, float *image, int row, int col, int channel, int *label, int labelRow, int labelCol, int batchSize, int iter) { int j; struct timespec startTime; struct timespec endTime; struct timespec fpStartTime; struct timespec fpEndTime; struct timespec bpStartTime; struct timespec bpEndTime; struct timespec layerStartTime; struct timespec layerEndTime; float time; int err; timlCNNLayer *bpStartLayer; timlCNNLayer *layer; float cost; long mem; err = 0; layer = cnn->head; timlCNNPrint(cnn); printf("Batch size = %d, iteration = %d.\n", batchSize, iter); // load image and label timlCNNLoadImage(cnn, image, row, col, channel, cnn->params.batchSize); timlCNNLoadLabel(cnn, label, labelRow, labelCol, cnn->params.batchSize); clock_gettime(CLOCK_REALTIME, &startTime); clock_gettime(CLOCK_REALTIME, &fpStartTime); clock_gettime(CLOCK_REALTIME, &layerStartTime); timlCNNInputForwardPropagation(layer); clock_gettime(CLOCK_REALTIME, &layerEndTime); time = timlUtilDiffTime(layerStartTime, layerEndTime); printf("[Forward] layer %d(%s) = %.2f us\n", layer->id, timlCNNLayerTypeStr(layer), time); while (layer->next != NULL) { clock_gettime(CLOCK_REALTIME, &layerStartTime); for (j = 0; j < iter; j++) { switch (layer->next->type) { case CNN_Softmax: timlCNNSoftmaxForwardPropagation(layer); break; case CNN_Accuracy: timlCNNAccuracyForwardPropagation(layer); break; case CNN_SoftmaxCost: timlCNNSoftmaxCostForwardPropagation(layer); break; case CNN_Conv: timlCNNConvForwardPropagation(layer); break; case CNN_Norm: timlCNNNormForwardPropagation(layer); break; case CNN_Pooling: timlCNNPoolingForwardPropagation(layer); break; case CNN_Linear: timlCNNLinearForwardPropagation(layer); break; case CNN_Nonlinear: timlCNNNonlinearForwardPropagation(layer); break; case CNN_Dropout: timlCNNDropoutForwardPropagation(layer); break; default: break; } } clock_gettime(CLOCK_REALTIME, &layerEndTime); time = timlUtilDiffTime(layerStartTime, layerEndTime); printf("[Forward] layer %d(%s) = %.2f us\n", layer->next->id, timlCNNLayerTypeStr(layer->next), time); layer = layer->next; } clock_gettime(CLOCK_REALTIME, &fpEndTime); time = timlUtilDiffTime(fpStartTime, fpEndTime); printf("[Forward] total time = %.2f us\n", time); if (cnn->params.phase == Util_Test) { return err; } // back propagation clock_gettime(CLOCK_REALTIME, &bpStartTime); while (layer->prev != NULL) { clock_gettime(CLOCK_REALTIME, &layerStartTime); for (j = 0; j < iter; j++) { switch (layer->type) { case CNN_Input: break; case CNN_Conv: timlCNNConvBackPropagation(layer); break; case CNN_Pooling: timlCNNPoolingBackPropagation(layer); break; case CNN_Norm: timlCNNNormBackPropagation(layer); break; case CNN_Nonlinear: timlCNNNonlinearBackPropagation(layer); break; case CNN_Linear: timlCNNLinearBackPropagation(layer); break; case CNN_Dropout: timlCNNDropoutBackPropagation(layer); break; case CNN_SoftmaxCost: timlCNNSoftmaxCostBackPropagation(layer); break; case CNN_Softmax: timlCNNSoftmaxBackPropagation(layer); break; default: break; } } clock_gettime(CLOCK_REALTIME, &layerEndTime); time = timlUtilDiffTime(layerStartTime, layerEndTime); printf("[Backward] layer %d(%s) = %.2f us\n", layer->id, timlCNNLayerTypeStr(layer), time); layer = layer->prev; } clock_gettime(CLOCK_REALTIME, &bpEndTime); clock_gettime(CLOCK_REALTIME, &endTime); time = timlUtilDiffTime(bpStartTime, bpEndTime); printf("[Backward] total time = %.2f us\n", time); time = timlUtilDiffTime(startTime, endTime); printf("total time = %.2f us\n", time); return err; }