1# Licensed to the Apache Software Foundation (ASF) under one 2# or more contributor license agreements. See the NOTICE file 3# distributed with this work for additional information 4# regarding copyright ownership. The ASF licenses this file 5# to you under the Apache License, Version 2.0 (the 6# "License"); you may not use this file except in compliance 7# with the License. You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, 12# software distributed under the License is distributed on an 13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14# KIND, either express or implied. See the License for the 15# specific language governing permissions and limitations 16# under the License. 17 18package AI::MXNet::NDArray::Slice; 19use strict; 20use warnings; 21use Mouse; 22use AI::MXNet::Base; 23use AI::MXNet::Function::Parameters; 24 25=head1 NAME 26 27 AI::MXNet::NDArray::Slice - A convenience class for slicing of the AI::MXNet::NDArray objects. 28=cut 29 30has parent => (is => 'ro', isa => 'AI::MXNet::NDArray', required => 1); 31has begin => (is => 'ro', isa => 'Shape', required => 1); 32has end => (is => 'ro', isa => 'Shape', required => 1); 33use overload 34 '.=' => \&set, 35 '=' => sub { $_[0] }, 36 '""' => sub { my $self = $_[0]->sever; "$self" }, 37 '**' => sub { my $self = $_[0]->sever; $self ** $_[1] }, 38 '==' => sub { my $self = $_[0]->sever; $self == $_[1] }, 39 '!=' => sub { my $self = $_[0]->sever; $self != $_[1] }, 40 '+' => sub { my $self = $_[0]->sever; $self + $_[1] }, 41 '*' => sub { my $self = $_[0]->sever; $self * $_[1] }, 42 '-' => sub { my $self = $_[0]->sever; $_[2] ? $_[1] - $self : $self - $_[1] }, 43 '/' => sub { my $self = $_[0]->sever; $_[2] ? $_[1] / $self : $self / $_[1] }, 44 '+=' => sub { my ($self, $other) = @_; my $in = $self->sever; $self .= ($in+$_[1]) }, 45 '-=' => sub { my ($self, $other) = @_; my $in = $self->sever; $self .= ($in-$_[1]) }, 46 '*=' => sub { my ($self, $other) = @_; my $in = $self->sever; $self .= ($in*$_[1]) }, 47 '/=' => sub { my ($self, $other) = @_; my $in = $self->sever; $self .= ($in/$_[1]) }, 48 '**='=> sub { my ($self, $other) = @_; my $in = $self->sever; $self .= ($in**$_[1]) }, 49 '>' => sub { my $self = $_[0]->sever; return $_[2] ? $_[1] > $self : $self > $_[1] }, 50 '>=' => sub { my $self = $_[0]->sever; return $_[2] ? $_[1] >= $self : $self >= $_[1] }, 51 '<' => sub { my $self = $_[0]->sever; return $_[2] ? $_[1] < $self : $self < $_[1] }, 52 '<=' => sub { my $self = $_[0]->sever; return $_[2] ? $_[1] <= $self : $self <= $_[1] }; 53 54method set(AcceptableInput $value, $reverse=) 55{ 56 confess("set value must be defined") unless defined $value; 57 confess("${\ $self->parent } is not writable") unless $self->parent->writable; 58 my $shape = [ map { 59 my($begin, $end) = @$_; 60 ($end-$begin); 61 } zip($self->begin, $self->end) ]; 62 if(ref $value) 63 { 64 if(blessed($value) and $value->isa('AI::MXNet::NDArray')) 65 { 66 $value = $value->as_in_context($self->parent->context); 67 } 68 elsif(blessed($value) and $value->isa('AI::MXNet::NDArray::Slice')) 69 { 70 $value = $value->sever->as_in_context($self->parent->context); 71 } 72 else 73 { 74 $value = AI::MXNet::NDArray->array($value, ctx => $self->parent->context); 75 } 76 confess("value $value does not match slice dim sizes [@$shape]") 77 if @{$value->shape} != @$shape; 78 for(zip($shape, $value->shape)) { 79 my ($dsize, $vdsize) = @$_; 80 confess("Slice [@$shape] != $value given as value") 81 if $dsize != $vdsize; 82 } 83 AI::MXNet::NDArray->_crop_assign( 84 $self->parent, 85 $value, 86 { out => $self->parent, begin => $self->begin, end => $self->end } 87 ); 88 } 89 else 90 { 91 AI::MXNet::NDArray->_crop_assign_scalar( 92 $self->parent, 93 { "scalar" => $value, out => $self->parent, begin => $self->begin, end => $self->end } 94 ); 95 } 96 return $self->parent; 97} 98 99method sever() 100{ 101 return AI::MXNet::NDArray->crop( 102 $self->parent, 103 { begin => $self->begin, end => $self->end } 104 ); 105} 106 107{ 108 no warnings 'misc'; 109 use attributes 'AI::MXNet::NDArray::Slice', \&AI::MXNet::NDArray::Slice::sever, 'lvalue'; 110} 111 112sub notsupported { confess("NDArray only support continuous slicing on axis 0"); } 113sub AUTOLOAD { 114 my $sub = $AI::MXNet::NDArray::Slice::AUTOLOAD; 115 $sub =~ s/.*:://; 116 my $self = shift; 117 return $self->sever->$sub(@_); 118} 119 1201; 121