AI-MXNet
view release on metacpan or search on metacpan
lib/AI/MXNet/NDArray.pm view on Meta::CPAN
array : PDL
A copy of the array content.
=cut
method aspdl()
{
my $dtype = $self->dtype;
my $pdl_type = PDL::Type->new(DTYPE_MX_TO_PDL->{ $dtype });
my $pdl = PDL->new_from_specification($pdl_type, reverse @{ $self->shape });
my $perl_pack_type = DTYPE_MX_TO_PERL->{$dtype};
my $buf = pack("$perl_pack_type*", (0)x$self->size);
check_call(AI::MXNetCAPI::NDArraySyncCopyToCPU($self->handle, $buf, $self->size));
## special handling for float16
if($perl_pack_type eq 'S')
{
$buf = pack("f*", map { AI::MXNetCAPI::_half_to_float($_) } unpack("S*", $buf));
}
${$pdl->get_dataref} = $buf;
$pdl->upd_data;
return $pdl;
}
=head2 asmpdl
Returns copied PDL::Matrix objectt of current array.
Requires caller to "use PDL::Matrix" in user space.
Returns
-------
array : PDL::Matrix
A copy of array content.
=cut
method asmpdl()
{
my $dtype = $self->dtype;
my $pdl_type = PDL::Type->new(DTYPE_MX_TO_PDL->{ $dtype });
my $pdl = PDL::Matrix->new_from_specification($pdl_type, @{ $self->shape });
my $perl_pack_type = DTYPE_MX_TO_PERL->{$dtype};
my $buf = pack("$perl_pack_type*", (0)x$self->size);
check_call(AI::MXNetCAPI::NDArraySyncCopyToCPU($self->handle, $buf, $self->size));
## special handling for float16
if($perl_pack_type eq 'S')
{
$buf = pack("f*", map { AI::MXNetCAPI::_half_to_float($_) } unpack("S*", $buf));
}
${$pdl->get_dataref} = $buf;
$pdl->upd_data;
return $pdl;
}
=head2 _slice
Returns sliced NDArray that shares memory with the current one.
Parameters
----------
start : int
Starting index of slice.
stop : int
Finishing index of slice.
=cut
method _slice (
Index $start,
Index $stop
)
{
confess("start $start > stop $stop") if $start > $stop;
my $handle = check_call(
AI::MXNetCAPI::NDArraySlice(
$self->handle,
$start,
$stop
)
);
return __PACKAGE__->new(handle => $handle, writable => $self->writable);
}
=head2 _at
Returns a sub NDArray that shares memory with current one.
Parameters
----------
idx : int
index of the sub array.
=cut
method _at(Index $idx)
{
my $handle = check_call(
AI::MXNetCAPI::NDArrayAt(
$self->handle, $idx >=0 ? $idx : $self->shape->[0] + $idx
)
);
return __PACKAGE__->new(handle => $handle, writable => $self->writable);
}
=head2 reshape
Returns a reshaped NDArray that shares the memory with current one.
One shape dimension can be -1. In this case, the value is inferred
from the length of the array and remaining dimensions.
Parameters
----------
new_shape : Shape
new shape of NDArray
=cut
method reshape(ArrayRef[Int] $new_shape)
{
my $i = -1;
my @inferred = map { $i++; $_ == -1 ? ($i) : () } @$new_shape;
assert((@inferred <= 1), 'Only one dimension can be inferred.');
if(@inferred)
{
$new_shape->[$inferred[0]] = product(@{ $self->shape })/product(map { abs($_) } @{ $new_shape });
}
my $handle = check_call(
AI::MXNetCAPI::NDArrayReshape(
$self->handle,
scalar(@$new_shape),
$new_shape
)
);
return __PACKAGE__->new(handle => $handle, writable => $self->writable);
}
=head2 ndim
lib/AI/MXNet/NDArray.pm view on Meta::CPAN
{
confess("no arrays provided") unless @$arrays > 0;
if(not $always_copy and @$arrays == 1)
{
return $arrays->[0];
}
my $shape_axis = $arrays->[0]->shape->[$axis];
my $shape_rest1 = [@{ $arrays->[0]->shape }[0..($axis-1)]];
my $shape_rest2 = [@{ $arrays->[0]->shape }[($axis+1)..(@{ $arrays->[0]->shape }-1)]];
my $dtype = $arrays->[0]->dtype;
my $i = 1;
for my $arr (@{ $arrays }[1..(@{ $arrays }-1)])
{
$shape_axis += $arr->shape->[$axis];
my $arr_shape_rest1 = [@{ $arr->shape }[0..($axis-1)]];
my $arr_shape_rest2 = [@{ $arr->shape }[($axis+1)..(@{ $arr->shape }-1)]];
confess("first array $arrays->[0] and $i array $arr do not match")
unless join(',',@$arr_shape_rest1) eq join(',',@$shape_rest1);
confess("first array $arrays->[0] and $i array $arr do not match")
unless join(',',@$arr_shape_rest2) eq join(',',@$shape_rest2);
confess("first array $arrays->[0] and $i array $arr dtypes do not match")
unless join(',',@$arr_shape_rest2) eq join(',',@$shape_rest2);
$i++;
}
my $ret_shape = [@$shape_rest1, $shape_axis, @$shape_rest2];
my $ret = __PACKAGE__->empty($ret_shape, ctx => $arrays->[0]->context, dtype => $dtype);
my $idx = 0;
my $begin = [(0)x@$ret_shape];
my $end = [@$ret_shape];
for my $arr (@$arrays)
{
if ($axis == 0)
{
$ret->slice([$idx,($idx+$arr->shape->[0]-1)]) .= $arr;
}
else
{
$begin->[$axis] = $idx;
$end->[$axis] = $idx+$arr->shape->[$axis];
__PACKAGE__->_crop_assign(
$ret, $arr,
{
out => $ret,
begin => $begin,
end => $end
}
);
}
$idx += $arr->shape->[$axis];
}
return $ret
}
=head2 arange
Similar function in the MXNet ndarray as numpy.arange
See Also https://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html.
Parameters
----------
:$start=0 : number, optional
Start of interval. The interval includes this value. The default start value is 0.
$stop= : number, optional
End of interval. The interval does not include this value.
:$step=1 : number, optional
Spacing between the values
:$repeat=1 : number, optional
The repeating time of all elements.
E.g repeat=3, the element a will be repeated three times --> a, a, a.
:$ctx : Context, optional
The context of the NDArray, defaultw to current default context.
:$dtype : data type, optional
The value type of the NDArray, defaults to float32
Returns
-------
$out : NDArray
The created NDArray
=cut
method arange(Index :$start=0, Index :$stop=, Index :$step=1, Index :$repeat=1,
AI::MXNet::Context :$ctx=AI::MXNet::Context->current_ctx, Dtype :$dtype='float32')
{
return __PACKAGE__->_arange({
start => $start,
(defined $stop ? (stop => $stop) : ()),
step => $step,
repeat => $repeat,
dtype => $dtype,
ctx => "$ctx"
});
}
=head2 load
Loads ndarrays from a binary file.
You can also use Storable to do the job if you only work with Perl.
The advantage of load/save is the file is language agnostic.
This means the file saved using save can be loaded by other language binding of mxnet.
You also get the benefit being able to directly load/save from cloud storage(S3, HDFS)
Parameters
----------
fname : str
The name of the file.Can be S3 or HDFS address (remember built with S3 support).
Example of fname:
- `s3://my-bucket/path/my-s3-ndarray`
- `hdfs://my-bucket/path/my-hdfs-ndarray`
- `/path-to/my-local-ndarray`
Returns
-------
$out : array ref of NDArrays or hash ref with NDArrays
=cut
method load(Str $filename)
{
my ($handles, $names) = check_call(AI::MXNetCAPI::NDArrayLoad($filename));
if (not @$names)
{
return [map { __PACKAGE__->new(handle => $_) } @$handles];
}
else
{
my $n = @$names;
my $h = @$handles;
confess("Handles [$h] and names [$n] count mismatch") unless $h == $n;
my %ret;
@ret{ @$names } = map { __PACKAGE__->new(handle => $_) } @$handles;
return \%ret;
}
}
=head2 save
Save array ref of NDArray or hash of str->NDArray to a binary file.
You can also use Storable to do the job if you only work with Perl.
The advantage of load/save is the file is language agnostic.
This means the file saved using save can be loaded by other language binding of mxnet.
You also get the benefit being able to directly load/save from cloud storage(S3, HDFS)
Parameters
( run in 0.631 second using v1.01-cache-2.11-cpan-39bf76dae61 )