AI-MXNet
view release on metacpan or search on metacpan
lib/AI/MXNet/NDArray.pm view on Meta::CPAN
ndarray only supports either ->at on dimension 0
or full crop")
if $isize > 1 and $dsize != $isize;
my $i = 0;
zip(sub {
my ($idx, $dim_size) = @_;
confess("Dimension $i mismatch Idx: $idx >= Dim Size: $dim_size")
if $idx >= $dim_size or ($idx + $dim_size) < 0;
++$i;
}, \@indices, $shape);
$i = 0;
for my $v (@indices)
{
$v += $shape->[$i] if $v < 0;
++$i;
}
return $self->_at($indices[0]) if @indices == 1;
return $self->slice(@indices);
}
method slice(Slice @slices)
{
confess("No slices supplied") unless @slices;
my $shape = $self->shape;
my $dsize = @$shape;
my $isize = @slices;
confess("Dimensions size $dsize < slices size $isize")
if $dsize < $isize;
confess("Dimensions size $dsize != slices size $isize,
ndarray only supports either ->slice on dimension 0
or full crop")
if $isize > 1 and $dsize != $isize;
my $i = -1;
@slices = map {
++$i;
ref $_ ? (@$_ == 1 ? [$_->[0], $shape->[$i] - 1] : $_) : ($_ eq 'X' ? [0, $shape->[$i] - 1] : [$_, $_]);
} @slices;
zip(sub {
my ($slice, $dim_size) = @_;
my ($begin, $end, $stride) = @$slice;
confess("NDArray does not support slice strides != 1")
if ($stride//0) > 1;
confess("Dimension $i mismatch slice begin : $begin >= Dim Size: $dim_size")
if $begin >= $dim_size or ($begin + $dim_size) < 0;
confess("Dimension $i mismatch slice end : $end >= Dim Size: $dim_size")
if $end >= $dim_size or ($end + $dim_size) < 0;
}, \@slices, $shape);
$i = 0;
my ($begin, $end) = ([], []);
for my $s (@slices)
{
$s->[0] += $shape->[$i] if $s->[0] < 0;
$s->[1] += $shape->[$i] if $s->[1] < 0;
confess("Dimension $i slice mismatch (begin $s->[0] > end $s->[1])")
if($s->[0] > $s->[1]);
push @$begin, $s->[0];
push @$end, $s->[1] + 1;
$i++;
}
return $self->_slice($begin->[0], $end->[0]) if @slices == 1;
return AI::MXNet::NDArray::Slice->new(parent => $self, begin => $begin, end => $end);
}
method set(AcceptableInput $value, $reverse=)
{
confess("set value must be defined") unless defined $value;
confess("Array is not writable") if not $self->writable;
## plain number
if(not ref $value)
{
$self->_set_value($value, { out => $self });
}
# ndarray
elsif(blessed($value) and $value->isa(__PACKAGE__))
{
$value->copyto($self);
}
# slice of another ndarray
elsif(blessed($value) and $value->isa('AI::MXNet::NDArray::Slice'))
{
$value->sever->copyto($self);
}
# perl array, PDL, PDL::Matrix
else
{
$self->_sync_copyfrom($value);
}
return $self;
}
method asscalar()
{
confess("ndarray size must be 1") unless $self->size == 1;
return $self->aspdl->at(0);
}
method _sync_copyfrom(ArrayRef|PDL|PDL::Matrix $source_array)
{
my $dtype = $self->dtype;
my $pdl_type = PDL::Type->new(DTYPE_MX_TO_PDL->{ $dtype });
if(not blessed($source_array))
{
$source_array = eval {
pdl($pdl_type, $source_array);
};
confess($@) if $@;
}
if($pdl_type->numval != $source_array->type->numval)
{
my $convert_func = $pdl_type->convertfunc;
$source_array = $source_array->$convert_func;
}
$source_array = pdl($pdl_type, [@{ $source_array->unpdl } ? $source_array->unpdl->[0] : 0 ])
unless @{ $source_array->shape->unpdl };
my $pdl_shape = $source_array->shape->unpdl;
my $pdl_shape_str = join(',', ref($source_array) eq 'PDL' ? reverse @{ $pdl_shape } : @{ $pdl_shape });
my $ndary_shape_str = join(',', @{ $self->shape });
if($pdl_shape_str ne $ndary_shape_str)
{
confess("Shape inconsistant: expected $ndary_shape_str vs got $pdl_shape_str")
}
( run in 0.975 second using v1.01-cache-2.11-cpan-2398b32b56e )