| #ifndef TH_GENERIC_FILE |
| #define TH_GENERIC_FILE "generic/HardTanh.c" |
| #else |
| |
| void THNN_(HardTanh_updateOutput)( |
| THNNState *state, |
| THTensor *input, |
| THTensor *output, |
| accreal min_val_, |
| accreal max_val_, |
| bool inplace) |
| { |
| real min_val = TH_CONVERT_ACCREAL_TO_REAL(min_val_); |
| real max_val = TH_CONVERT_ACCREAL_TO_REAL(max_val_); |
| if (inplace) |
| THTensor_(set)(output, input); |
| else |
| THTensor_(resizeAs)(output, input); |
| |
| if (input->nDimension == 1 || !THTensor_(isContiguous)(input) || !THTensor_(isContiguous)(output)) |
| { |
| if (inplace) |
| TH_TENSOR_APPLY(real, input, |
| if (*input_data < min_val) |
| *input_data = min_val; |
| else if (*input_data > max_val) |
| *input_data = max_val; |
| ); |
| TH_TENSOR_APPLY2(real, output, real, input, |
| if (*input_data < min_val) |
| *output_data = min_val; |
| else if (*input_data <= max_val) |
| *output_data = *input_data; |
| else |
| *output_data = max_val; |
| ); |
| } |
| else |
| { |
| real* ptr_input = THTensor_(data)(input); |
| real* ptr_output = THTensor_(data)(output); |
| ptrdiff_t i; |
| ptrdiff_t n = THTensor_(nElement)(input); |
| |
| if (inplace) |
| #pragma omp parallel for private(i) |
| for (i = 0; i < n; i++) |
| { |
| if (ptr_input[i] < min_val) |
| ptr_input[i] = min_val; |
| else if (ptr_input[i] > max_val) |
| ptr_input[i] = max_val; |
| } |
| else |
| #pragma omp parallel for private(i) |
| for (i = 0; i < n; i++) |
| { |
| if (ptr_input[i] < min_val) |
| ptr_output[i] = min_val; |
| else if (ptr_input[i] <= max_val) |
| ptr_output[i] = ptr_input[i]; |
| else |
| ptr_output[i] = max_val; |
| } |
| } |
| } |
| |
| void THNN_(HardTanh_updateGradInput)( |
| THNNState *state, |
| THTensor *input, |
| THTensor *gradOutput, |
| THTensor *gradInput, |
| accreal min_val_, |
| accreal max_val_, |
| bool inplace) |
| { |
| real min_val = TH_CONVERT_ACCREAL_TO_REAL(min_val_); |
| real max_val = TH_CONVERT_ACCREAL_TO_REAL(max_val_); |
| |
| THNN_CHECK_NELEMENT(input, gradOutput); |
| if (inplace) |
| THTensor_(set)(gradInput, gradOutput); |
| else |
| THTensor_(resizeAs)(gradInput, input); |
| |
| if (input->nDimension == 1 || |
| !THTensor_(isContiguous)(input) || |
| !THTensor_(isContiguous)(gradOutput) || |
| !THTensor_(isContiguous)(gradInput)) |
| { |
| if (inplace) |
| { |
| TH_TENSOR_APPLY2(real, gradOutput, real, input, |
| if (*input_data <= min_val || *input_data >= max_val) |
| *gradOutput_data = 0; |
| ); |
| } |
| else |
| TH_TENSOR_APPLY3(real, gradInput, real, gradOutput, real, input, |
| if (*input_data <= min_val || *input_data >= max_val) |
| *gradInput_data = 0; |
| else |
| *gradInput_data = *gradOutput_data; |
| ); |
| } |
| else |
| { |
| real* ptr_gradOutput = THTensor_(data)(gradOutput); |
| real* ptr_gradInput = THTensor_(data)(gradInput); |
| real* ptr_input = THTensor_(data)(input); |
| ptrdiff_t i; |
| ptrdiff_t n = THTensor_(nElement)(input); |
| |
| if (inplace) |
| #pragma omp parallel for private(i) |
| for (i = 0; i < n; i++) |
| { |
| if (ptr_input[i] <= min_val || ptr_input[i] >= max_val) |
| ptr_gradInput[i] = 0; |
| } |
| else |
| #pragma omp parallel for private(i) |
| for (i = 0; i < n; i++) |
| { |
| if (ptr_input[i] <= min_val || ptr_input[i] >= max_val) |
| ptr_gradInput[i] = 0; |
| else |
| ptr_gradInput[i] = ptr_gradOutput[i]; |
| } |
| } |
| } |
| |
| #endif |