void min(const T* arg, T* out, const Shape& in_shape, const Shape& out_shape, const AxisSet& reduction_axes) { T minval = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : std::numeric_limits<T>::max(); CoordinateTransform output_transform(out_shape); for (const Coordinate& output_coord : output_transform) { out[output_transform.index(output_coord)] = minval; } CoordinateTransform input_transform(in_shape); for (const Coordinate& input_coord : input_transform) { Coordinate output_coord = project(input_coord, reduction_axes); T x = arg[input_transform.index(input_coord)]; T min = out[output_transform.index(output_coord)]; if (x < min) { out[output_transform.index(output_coord)] = x; } } }
void reverse(const T* arg, T* out, const Shape& arg_shape, const Shape& out_shape, const AxisSet& reversed_axes) { // In fact arg_shape == out_shape, but we'll use both for stylistic consistency with other kernels. CoordinateTransform arg_transform(arg_shape); CoordinateTransform output_transform(out_shape); for (Coordinate out_coord : output_transform) { Coordinate arg_coord = out_coord; for (size_t i = 0; i < arg_coord.size(); i++) { if (reversed_axes.count(i) != 0) { arg_coord[i] = arg_shape[i] - arg_coord[i] - 1; } } out[output_transform.index(out_coord)] = arg[arg_transform.index(arg_coord)]; } }
BICAPI void safe_compute_transform_from_tags( int npoints, Real **tag_list1, Real **tag_list2, Trans_type trans_type, General_transform *transform ) { #if !HAVE_FORK compute_transform_from_tags( npoints, tag_list1, tag_list2, trans_type, transform ); #else int fildes[2]; FILE *fpin, *fpout; Status status; int statptr; General_transform computed_transform; /* Create a pipe */ if (pipe(fildes)) { create_linear_transform(transform, NULL); return; } /* Fork */ if (fork()) { /* Parent */ (void) close(fildes[1]); fpin = fdopen(fildes[0], "r"); status = input_transform(fpin, NULL, transform); (void) fclose(fpin); do { (void) wait(&statptr); } while (WIFSTOPPED(statptr)); if (WEXITSTATUS(statptr) || status != OK) { if( status == OK ) delete_general_transform( transform ); create_linear_transform(transform, NULL); return; } } else { /* Child */ (void) close(fildes[0]); fpout = fdopen(fildes[1], "w"); compute_transform_from_tags(npoints, tag_list1, tag_list2, trans_type, &computed_transform); status = output_transform(fpout, NULL, NULL, NULL, &computed_transform); delete_general_transform( &computed_transform ); (void) fclose(fpout); if (status != OK) { exit(EXIT_FAILURE); } else { exit(EXIT_SUCCESS); } } return; #endif }
void sum(const T* arg, T* out, const Shape& in_shape, const Shape& out_shape, const AxisSet& reduction_axes) { CoordinateTransform output_transform(out_shape); for (const Coordinate& output_coord : output_transform) { out[output_transform.index(output_coord)] = 0; } CoordinateTransform input_transform(in_shape); for (const Coordinate& input_coord : input_transform) { Coordinate output_coord = project(input_coord, reduction_axes); out[output_transform.index(output_coord)] += arg[input_transform.index(input_coord)]; } }
void max_pool(const T* arg, T* out, const Shape& arg_shape, const Shape& out_shape, const Shape& window_shape, const Strides& window_movement_strides, const Shape& padding_below, const Shape& padding_above) { // At the outermost level we will walk over every output coordinate O. CoordinateTransform output_transform(out_shape); for (const Coordinate& out_coord : output_transform) { // Our output coordinate O will have the form: // // (N,chan,i_1,...,i_n) size_t batch_index = out_coord[0]; size_t channel = out_coord[1]; // For the input data we need to iterate the coordinate: // // I: // // over the range (noninclusive on the right): // // (N,chan,s_1*i_1,s_2*i_2,...,s_n*i_n) -> // // (N+1,chan+1,s_1*i_1 + window_shape_1,...,s_n*i_n + window_shape_n) // // with unit stride. // // We iterate this over the *padded* data, so below we will need to check for coordinates that fall in the padding area. size_t n_spatial_dimensions = arg_shape.size() - 2; Coordinate input_batch_transform_start(2 + n_spatial_dimensions); Coordinate input_batch_transform_end(2 + n_spatial_dimensions); Strides input_batch_transform_source_strides(2 + n_spatial_dimensions, 1); AxisVector input_batch_transform_source_axis_order(2 + n_spatial_dimensions); CoordinateDiff input_batch_transform_padding_below(2 + n_spatial_dimensions); CoordinateDiff input_batch_transform_padding_above(2 + n_spatial_dimensions); input_batch_transform_start[0] = batch_index; input_batch_transform_end[0] = batch_index + 1; input_batch_transform_start[1] = channel; input_batch_transform_end[1] = channel + 1; input_batch_transform_padding_below[0] = 0; input_batch_transform_padding_below[1] = 0; input_batch_transform_padding_above[0] = 0; input_batch_transform_padding_above[1] = 0; for (size_t i = 2; i < n_spatial_dimensions + 2; i++) { size_t window_shape_this_dim = window_shape[i - 2]; size_t movement_stride = window_movement_strides[i - 2]; input_batch_transform_start[i] = movement_stride * out_coord[i]; input_batch_transform_end[i] = input_batch_transform_start[i] + window_shape_this_dim; input_batch_transform_padding_below[i] = padding_below[i - 2]; input_batch_transform_padding_above[i] = padding_above[i - 2]; } for (size_t i = 0; i < arg_shape.size(); i++) { input_batch_transform_source_axis_order[i] = i; } CoordinateTransform input_batch_transform( arg_shape, input_batch_transform_start, input_batch_transform_end, input_batch_transform_source_strides, input_batch_transform_source_axis_order, input_batch_transform_padding_below, input_batch_transform_padding_above); // As we go, we compute the maximum value: // // output[O] = max(output[O],arg[I]) T result = std::numeric_limits<T>::lowest(); for (const Coordinate& input_batch_coord : input_batch_transform) { if (input_batch_transform.has_source_coordinate(input_batch_coord)) { T x = arg[input_batch_transform.index(input_batch_coord)]; result = x > result ? x : result; } } out[output_transform.index(out_coord)] = result; } }
void pad(const T* arg0, const T* arg1, T* out, const Shape& arg0_shape, const Shape& out_shape, const Shape& padding_below, const Shape& padding_above, const Shape& padding_interior) { Coordinate input_start(arg0_shape.size(), 0); // start at (0,0,...,0) Coordinate input_end = out_shape; // end at (d'0,d'1,...,d'n), the outer corner of the post-padding shape Strides input_strides(arg0_shape.size(), 1); AxisVector input_axis_order(arg0_shape.size()); for (size_t i = 0; i < arg0_shape.size(); i++) { input_axis_order[i] = i; } Strides input_dilation(arg0_shape.size()); for (size_t i = 0; i < arg0_shape.size(); i++) { input_dilation[i] = padding_interior[i] + 1; } // Need to cast these to CoordinateDiff in order to make CoordinateTransform happy. CoordinateDiff padding_below_signed; CoordinateDiff padding_above_signed; for (size_t i = 0; i < padding_below.size(); i++) { padding_below_signed.push_back(padding_below[i]); padding_above_signed.push_back(padding_above[i]); } CoordinateTransform input_transform(arg0_shape, input_start, input_end, input_strides, input_axis_order, padding_below_signed, padding_above_signed, input_dilation); CoordinateTransform output_transform(out_shape); CoordinateTransform::Iterator output_it = output_transform.begin(); for (const Coordinate& in_coord : input_transform) { const Coordinate& out_coord = *output_it; T v = input_transform.has_source_coordinate(in_coord) ? arg0[input_transform.index(in_coord)] : *arg1; out[output_transform.index(out_coord)] = v; ++output_it; } }