Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling


( #480=superdoc: print w/replies, xml ) Need Help??

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
Let's finish Imager::GIF
1 direct reply — Read more / Contribute
by Anonymous Monk
on Feb 06, 2020 at 16:42
    Imager::GIF - a handy module for animated GIF processing - is a nice thought, with one semi-working method and problematic documentation (Re^2: Imager::GIF seems broken), that needs some help, as the docs say:


      Implement the rest of the transformations (cropping, rotating etc).

    I needed to non-proportionally scale animated GIFs and implemented type=>nonprop in the scale method. Other desirable features include crop, watermark, and sharpening. Please share your mods and methods here.



    Your local file:

    perl -MImager::GIF -le 'for (keys %INC) { print $INC{$_} if /GIF\.pm/ +}'
    My scale method:
    sub scale { my ($self, %args) = @_; my $ratio = $args{scalefactor} // 1; my $qtype = $args{qtype} // 'mixing'; # add qtype support $self->_mangle(sub { my $img = shift; my $ret = $img->scale(%args, qtype => $qtype); my $h = $img->tags(name => 'gif_screen_height'); my $w = $img->tags(name => 'gif_screen_width'); # add non-proportional scaling if ( $args{xpixels} and $args{ypixels} and $args{type} and $args{type} eq 'nonprop') { my $xratio = defined $args{xpixels} ? $args{xpixels} / $w : $ratio; my $yratio = defined $args{ypixels} ? $args{ypixels} / $w : $ratio; $ret->settag(name => 'gif_left', value => int($xratio * $img->tags(name => 'gif +_left'))); $ret->settag(name => 'gif_top', value => int($yratio * $img->tags(name => 'gif +_top'))); $ret->settag(name => 'gif_screen_width', value => int($xr +atio * $w)); $ret->settag(name => 'gif_screen_height', value => int($yr +atio * $h)); } else { # proportional scaling, from the original unless ($ratio) { if (defined $args{xpixels}) { $ratio = $args{xpixels} / $w; } if (defined $args{ypixels}) { $ratio = $args{ypixels} / $h; } } $ret->settag(name => 'gif_left', value => int($ratio * $img->tags(name => 'gif +_left'))); $ret->settag(name => 'gif_top', value => int($ratio * $img->tags(name => 'gif +_top'))); $ret->settag(name => 'gif_screen_width', value => int($ra +tio * $w)); $ret->settag(name => 'gif_screen_height', value => int($ra +tio * $h)); } return $ret; }); }
    Thank you!
Looking for testers who use Microsoft compilers
1 direct reply — Read more / Contribute
by syphilis
on Feb 03, 2020 at 06:10

    As this is essentially a request for some testing to be done, I thought "Meditations" was probably the best place for it.
    I'm not actively seeking wisdom with this post but, of course, receiving wisdom is always fine, even if it hasn't been requested ;-)

    If you have a perl that you've built using a Microsoft Compiler, I'd be most interested to learn of any problems or failures involved in running:
    cpan -i List::Uniqnum
    In fact, feel free to provide feedback for any build of perl that you have.
    The cpantesters smokers have been happily chewing on List-Uniqnum-0.04 for a couple of days, but there are very few Windows smokers out there.
    And, AFAIK, none of those smokers employ Microsoft compilers.

    Of course, Darwin and Solaris are probably also missing from those cpantesters systems - so join in with them, too .... or anything else that takes your fancy.

    I released List::Uniqnum to test changes that I want to make to the dual-life module List::Util's uniqnum() function - in order to improve that function's portability.
    A new release of List::Util (Scalar-List-Utils-1.54) hit cpan over the weekend. It still doesn't utilize the changes I was hoping would be included.
    If you run cpan -i List::Util you'll probably find that it passes all tests and installs cleanly.

    List-Util-1.54's uniqnum function actually works correctly on Linux, unless perl was built with -Duselongdouble or -Dusequadmath - in which case the test suite still passes, but only because it doesn't run tests that will reveal the problem.
    1.54 works fine on Windows, too, but again only if perl's nvtype is double.
    For it to work correctly on Windows if perl's ivtype is long long, it also requires that perl was built with __USE_MINGW_ANSI_STDIO, which only started happening wih the release of 5.26.0.
    Thankfully, Strawberry Perl 5.26 onwards is built with __USE_MINGW_ANSI_STDIO defined.
    Try cpan -i List::Util on a 64-bit-integer build of Strawberry perl-5.24.0 or earlier, and you'll see a test failure.

    If you want to know what's failing with your particular installation of List::Util's uniqnum function, here is something you can run:
    use Config; # for test 5 use strict; use warnings; use List::Util qw(uniqnum); #use List::Uniqnum qw(uniqnum); my $count; # test 1 if(1.4142135623730951 != 1.4142135623730954) { $count = uniqnum(1.4142135623730951, 1.4142135623730954); print "test 1 failed (returned $count)\n" unless $count == 2; } # test 2 if(10.770329614269008063 != 10.7703296142690080625) { $count = uniqnum(10.770329614269008063, 10.7703296142690080625); print "test 2 failed (returned $count)\n" unless $count == 2; } # test 3 if(1005.1022829201930645202916159776901 != 1005.10228292019306452029161597769015) { $count = uniqnum(1005.1022829201930645202916159776901, 1005.10228292019306452029161597769015); print "test 3 failed (returned $count)\n" unless $count == 2; } # test 4 $count = uniqnum(0, -0.0); print "test 4 failed (returned $count)\n" unless $count == 1; # test 5 if($Config{ivsize} == 8) { # These 2 (the first is an IV, the second is an NV) # both exactly represent the value 762939453127 * (2 ** 21) $count = uniqnum(100000000000262144, 1.00000000000262144e+17); print "test 5 failed (returned $count)\n" unless $count == 1; }
    It only announces failures. If there's no output, then everything is good.
    If you install List::Uniqnum, you can then modify the script to test List::Uniqnum.
    If you do that, and it produces some output, please let me know.

Artificial Intelligence experiment
3 direct replies — Read more / Contribute
by PerlGuy(Tom)
on Feb 03, 2020 at 00:05
    I'm not really sure why, life experience I guess, but while studying and practicing Perl programming, an idea for artificial intelligence flashed into my mind.
    Bot 2
RFC: List of first day of each month
6 direct replies — Read more / Contribute
by TieUpYourCamel
on Jan 31, 2020 at 10:17
    My task here is to make a list of all of the "first day of the month" days between a start date and an end date. I'm interested to hear thoughts about my solution:
    use strict; use warnings; use Time::Piece; use feature 'say'; my $date = Time::Piece->strptime( localtime->year() - 4 . " 01 01", "%Y %m %d" ); my $endDate = localtime(); while ( $date <= $endDate ) { say $date; # Get the next first of the month by going to the end of the # month and add one day my $year = $date->year; my $mon = $date->mon; my $day = $date->month_last_day; $date = Time::Piece->strptime( "$year $mon $day", "%Y %m %d" ) +; $date += Time::Seconds::ONE_DAY; }
RFC: Peer to Peer Conceptual Search Engine
2 direct replies — Read more / Contribute
by PerlGuy(Tom)
on Jan 28, 2020 at 05:37

    I consider myself a very novice Perl programmer, though I've been studying and using Perl for, I don't even know how many years. 30 maybe. Still so much to learn and so little time.

    I got into programming because I wanted a better search engine than any that were available, back in the day, say 1995. (I still think a better search engine is needed and possible).

    But all the programmer's I approached about my idea said

Reinventing Moops
No replies — Read more | Post response
by tobyink
on Jan 14, 2020 at 05:20

    It seems every few years, I come up with some kind of weird syntax extension for doing OO programming in Perl. Moops was the most recent but while it's cool, it's built on some shaky foundations.

    I've been working on this thing MooX::Press for a little while now. It allows you to define a bunch of classes in one use statement. Like:

    use MooX::Press ( prefix => 'MyApp', role => [ 'Livestock', 'Pet', 'Milkable' => { can => [ 'milk' => sub { print "giving milk\n"; }, ], }, ], class => [ 'Animal' => { has => [ 'name' => { type => 'Str' }, 'colour', 'age' => { type => 'Num' }, 'status' => { enum => ['alive', 'dead'], default => 'alive' }, ], subclass => [ 'Panda', 'Cat' => { with => ['Pet'] }, 'Dog' => { with => ['Pet'] }, 'Cow' => { with => ['Livestock', 'Milkable'] }, 'Pig' => { with => ['Livestock'] }, ], }, ], ); my $porky = MyApp->new_pig(name => 'Porky'); print $porky->status, "\n";

    It's designed to be as declarative as possible; with the exception of a coderefs for defining your methods, it's pretty much just a big hash that could be serialized as JSON or YAML or whatever. Indeed, I've written portable::loader as a way of loading MooX::Press classes/roles from JSON or TOML and deciding their package namespace at runtime.

    It's also very opinionated about how your classes and roles should be interacted with. Although MyApp::Pig->new works, you are encouraged to use MyApp->new_pig instead. And if a Panda object needs to create a Pig (because that happens in nature, right?) then it should call $self->FACTORY->new_pig to do the business. MyApp is the factory package, and objects get created via that; objects can find their factory package using $self->FACTORY. There are ways to override some of MooX::Press's opinions, but it steers you in this direction.

    Anyway, recently I started looking at how to combine this with Keyword::Declare to create something Moops-like. This is the syntax I have currently got working:

    use v5.14; use strict; use warnings; use Data::Dumper; use MooX::Press::Declare prefix => 'MyApp', toolkit => 'Moo'; class Quux { version 3.1; extends Quuux; with Xyzzy; has foo : ( is => ro, type => 'Foo' ); has bar : ( type => 'Barrr' ); has nooo!; # exclamation mark means required constant yeah = 42; method say_stuff { my $self = shift; say $self->yeah + $self->nooo; } } my $obj = MyApp->new_quux( foo => MyApp->new_foo, bar => MyApp->new_bar_baz, nooo => 1, ); print Dumper($obj); $obj->say_stuff; # Note the order you define stuff mostly doesn't matter. # We used these classes above and define them now. class Quuux; role Xyzzy; class Foo; class Bar::Baz { type_name Barrr; }

    It's still early days, but it's coming along pretty nicely too. I'm impressed with how easy Keyword::Declare makes syntax extensions.

    Still to do: method signatures, method modifiers (before, around, after), type coercions, and custom factory methods. (These are all supported by MooX::Press, but not by the declarative syntax yet.)

Mini-Tutorial: Formats for Packing and Unpacking Numbers
1 direct reply — Read more / Contribute
by ikegami
on Jan 06, 2020 at 03:49

    pack and unpack are useful tools for generating strings of bytes for interchange and extracting values from such strings respectively. What follows is a table that represents the relevant formats in a convenient form.

    Category Type Byte Order Mnemonic
    Native Little-Endian (<) Big-Endian (>)
    Unsigned C "C" for char
    Signed c
    Unsigned S S< or v S> or n "S" for short
    Signed s s< or v! s> or n!
    Unsigned L L< or V L> or N "L" for long
    Signed l l< or V! l> or N!
    Unsigned Q Q< Q> "Q" for quad
    Signed q q< q>
    Types Used
    By This Build
    of perl
    UV (unsigned integer) J J< J> "J" is related to "I"
    IV (signed integer) j j< j>
    NV (floating-point) F F< F> "F" for float
    C Types for
    This Build
    of perl
    unsigned short int S! S!< S!> "S" for short
    signed short int s! s!< s!>
    unsigned int I! or I I!< or I< I!> or I> "I" for int
    signed int i! or i i!< or i< i!> or i>
    unsigned long int L! L!< L!> "L" for long
    signed long int l! l!< l!>
    float f f< f> "f" for float
    double d d< d> "d" for double
    long double D D< D> A bigger double


    • < and > indicate byte order. The small end of the bracket is at the least significant end of the number. (< for little-endian byte order, and > for big-endian byte order.) Can't be used with N/n and V/v.
    • For integers, ! signifies using the C types of this build of perl. N/n and V/v excepted.
    • For integers, uppercase indicates unsigned, and lowercase indicates signed. N/n and V/v excepted.
    • N and n are used for network (i.e. internet) byte order (BE), with the uppercase letter being used for the larger bitsize.
    • V and v are used for VAX byte order (LE), with the uppercase letter being used for the larger bitsize.
"exists $hash{key}" is slower than "$hash{key}"
3 direct replies — Read more / Contribute
by swl
on Jan 05, 2020 at 19:23

    UPDATE 2020-01-10: Actually, it's not. See subthread starting at 11111117.


    I decided to run some benchmarking on hash exists after some code profiling showed a reasonable amount of time spent on lines with next if exists $hash{$key}.

    This is largely in the context of code structured like the (very contrived) example below which uses the common idiom of skipping slow code if it has already been done or is not needed based on a tracking hash.

    my %done; my @data = (1..100); for (1..100) { push @data, int (rand() * 100); } for my $item (@data) { next if exists $done{$item}; # do something time consuming # ... $done{$item}++; }

    The code below tries combinations of exists and value checking. Assignment to variables is used to avoid "Useless use of hash element in void context" warnings, and the assignment to globals is to get a sense of how much the timings are related to bookkeeping of lexicals. I could disable warnings but it's the relative timing differences that are useful here, not the absolute times.

    Code was run using Strawberry perl 5.28.0, and the results are given in the table below (see code for key explanation).

    The main take home is that the value checks (v prefix) are all faster than the exists checks (e prefix). Assigning to global is faster, presumably because there is less bookkeeping involved, but it will be rare that one would use such a construct anyway.

    Rate evksvl evkrvl ecksvl eckrvl evksvg evkrvg vvksvl vvk +rvl vckrvl vcksvl vvksvg vvkrvg evksvl 10733145/s -- -5% -7% -12% -15% -18% -29% - +31% -32% -33% -41% -48% evkrvl 11290643/s 5% -- -2% -7% -10% -14% -25% - +27% -28% -29% -38% -45% ecksvl 11570664/s 8% 2% -- -5% -8% -12% -23% - +25% -27% -27% -36% -44% eckrvl 12176232/s 13% 8% 5% -- -3% -8% -19% - +21% -23% -23% -33% -41% evksvg 12572221/s 17% 11% 9% 3% -- -5% -17% - +19% -20% -21% -31% -39% evkrvg 13168623/s 23% 17% 14% 8% 5% -- -13% - +15% -17% -17% -28% -36% vvksvl 15082826/s 41% 34% 30% 24% 20% 15% -- +-2% -4% -5% -17% -27% vvkrvl 15461840/s 44% 37% 34% 27% 23% 17% 3% + -- -2% -3% -15% -25% vckrvl 15777625/s 47% 40% 36% 30% 25% 20% 5% + 2% -- -1% -13% -23% vcksvl 15909705/s 48% 41% 38% 31% 27% 21% 5% + 3% 1% -- -13% -23% vvksvg 18207860/s 70% 61% 57% 50% 45% 38% 21% +18% 15% 14% -- -12% vvkrvg 20580512/s 92% 82% 78% 69% 64% 56% 36% +33% 30% 29% 13% --

    So why is it that exists is slower than checking the value? My starting assumption was that exists should be faster, as getting a value requires checking that it exists first. However, looking that the source code, most of the hash key and value calls are passed through the same function, hv_common. So far as I can tell from reading the code, and based on my limited comprehension of the details, hv_common prioritises getting values over checking key existence and value assignment.

    So does this all matter and should code that uses exists $hash{$key} be changed to use $hash{$key}? Given that even the slowest of the benchmark snippets is running more than 10,000,000 per second, it does not matter at all for most use cases. One would need to be running hundreds of millions of calls for such a change to start to make a meaningful difference, and some would quite reasonably argue that billions of calls are needed.

    Maybe the perl source code could be optimised so exists is not slower, but whether this justifies any additional maintenance burden is not something I can answer.

Old Programmer New To Perl
13 direct replies — Read more / Contribute
by storm5510
on Jan 01, 2020 at 07:46

    Greetings! I am new to Perl. However, I have been a part-time programmer since 1988. I got my start at the local community college. I am retired and 64 years old.

    I was told by some folks at that membership here can be tough. I much prefer to do my own research. Asking questions, like here, is a last resort. I have found that reading others posts can often reveal a solution to what I need.

    As for Perl itself, I am using Strawberry on Windows 10 Pro x64 v1903. I can follow code as long as it is not really complex. This is all I have, for now.

    Have a pleasant New Year's Day.

How to Bisect Perl
No replies — Read more | Post response
by haukex
on Dec 27, 2019 at 14:42

    In several of my nodes, I've used bisection to figure out when certain bugs/features were fixed/introduced. I find this useful because it'll often uncover the discussion that went into a feature or the detailed reasons behind a bug. I thought I'd write about this process, since I don't always document how I ran each bisect.

    First, what is bisection? Basically, it's a (partly automated) binary search to find the exact commit where some behavior changed.

    A simplified example: Say you want to find out which Perl release s///r was introduced. So, you run perl -e 's///r' on the oldest Perl you've got, say 5.6, and on the newest, 5.30 - the former dies, the latter runs, confirming the change happened somewhere between those releases. So then you divide the search space into two, and run the same test on 5.18 - it works, so you now know the change must have happened between 5.6 and 5.18, and you don't need to test the other half of the search space. Divide the search space again, and run the test on 5.12 - it fails, so you know the change must have happened between 5.12 and 5.18. Repeat the process again, and eventually you'll find out that Perl 5.12 dies, but 5.14 works - so you've now confirmed that s///r was introduced in release 5.14, and you didn't have to test all 13 Perl releases from 5.6 to 5.30! (Technically, the change happened in a development version between those two releases, but for this example we've only looked at non-development releases as a stand-in for commits.)

    A real bisect is different from this example in that it works on the granularity of git commits, and it's mostly automated - the Perl source code includes scripts to assist you in running a git-bisect. And instead of using pre-built Perls, the bisection process will check out each commit of Perl and build it from scratch (even applying patches as needed to get older versions of Perl to compile). It can take half an hour to several hours to run a bisect, but once you set it running, you can go and do something else in the meantime.

Printing large numbers with commas to show thousands groups.
3 direct replies — Read more / Contribute
by jnorden
on Dec 26, 2019 at 20:13
    Here is yet another answer to this ancient and oft-asked question (for linux at least).

    The standard advice is found in perlfaq5, on perlmonks, and elsewhere. Using Number::Format or a commify() sub works well, but isn't very convenient for modifying existing code that was written with printf. It seems unlikely that perl's printf will ever support %'d and friends (see printf(3), scroll to "Flag Characters").

    However, almost any linux system has a /usr/bin/printf command with %' support. So, the simple definition

    sub cprintf {system('/usr/bin/printf', @_)}
    will let you use
    cprintf("There are at least %'d ways to do it!\n", 42e6)
    to print: There are at least 42,000,000 ways to do it!

    For this to work, your LC_NUMERIC environment variable should be set to a locale that has a "thousands separator", such as en_US.UTF-8. It seems to work quite well, at least for simple cases. To modify existing code, just change your printf's to cprintf's and add apostrophe's to the formats as needed. Less work than wrapping each argument with a subroutine call and changing each format to %s. It also helps keep things clear and readable.

    It's tempting to override the builtin printf, but that's not easy to do. The CORE documentation lists printf as a special keyword. (Playing with tied file-handles or other tricks might work, but doesn't seem worth it too me.)

    On the other hand, if you want to auto-magically commify *all* your %d's, you could use:

    sub cprintf { my($fmt)= shift; $fmt=~s/%(-?\d*)d/%'$1d/g; system('/usr/bin/printf', $fmt, @_) }
    And then  cprintf("%d", 42e6) will print 42,000,000.

    Happy Holidays, and best wishes for the new year!

Defining, Testing and Documenting Perl?
2 direct replies — Read more / Contribute
by LanX
on Dec 23, 2019 at 12:03

    I started to write a test script for "Boolean Operators" with and w/o "Short-Circuit" in Perl.

    And quickly found me needing to define and test "Truthiness" in Perl.

    (Wait ... "0 but true" is false? Remembered it differently ;-)

    And now I find myself obliged to also define "Contexts", because an empty list is also false.

    And "Data Types", because internally it's more difficult, than just Scalar, Array and Hash.

    It's a lot of work, but in the end it could help in many corners when done correctly:

    • Regression testing between Perl versions
    • Leading to a proper language definition
    • Bottom up documenting the language in POD
    • Helping to test cross implementations in other languages like in JS
    Properly done means that it needs to be axiomatic, i.e. higher level tests need to only use features proven in lower levels.

    Like so often, after a first success I find myself a bit stuck in the big picture.

    I'll throw in my first approach as is for meditation.

    There is a lot to be criticized, but my normal perfectionism is too risky and might lead to a never release cycle.


    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Perl hosting is hard to find
10 direct replies — Read more / Contribute
by harangzsolt33
on Dec 20, 2019 at 10:09
    I was searching for the cheapest Perl hosting online that also allows me to have 10 websites pointing to it. But I am finding out that cheapest is not necessarily good. Maybe I am wrong. But this is the third time I do business with a hosting company that promises to offer perl support and doesn't live up to its claims.

    I'm talking about Netfirms, 50webs, and These are the three I have tried and paid for. They promised I would get perl scripting, and it wasn't included. I was told to buy the next level up. But if I have to upgrade, then why did they include perl in their special offer or advertising!? Anyway, I didn't get what I paid for, and I was disappointed. Is it common to see hosting companies that say they offer perl and then not deliver on their promise? I mean that's the only reason I chose these hosts, because they included perl in the list.

Dataflow programming on CPU and GPU using AI::MXNet
1 direct reply — Read more / Contribute
by bliako
on Dec 18, 2019 at 07:04

    Computational pipelines, often called Dataflows, are just Graphs describing the interaction of Data with Operators and other Data to produce more Data.

    a*b + c*d is a Dataflow.

    And so is a (feed forward) Neural Network: read input, distribute input matrix to first layer, pass it through activations, sum outputs and distribute to second layer and so on until the output layer. Deep Neural Networks are so complex, deep and convoluted that they thought dataflow programming (which is not new as a field) will aid their training and use. And so TensorFlow and MXNet and others were created.

    The really unfortunate thing is that most of these frameworks are investing heavily on Python interfaces even if internally they use C/C++ for obvious reasons :) . The fact that Python is a TIOOWTDI regime will lead this field to serious cargo-culting (e.g. "In a sparse network, its more likely that neurons are actually processing meaningful aspects of the problem." which I have seen before when working with Neural Networks, mid-90's), script-kidding practices and eventual stagnation. Of course the field will recover. And faster and sooner, if and when Python is replaced or other high-level-er (script) languages are equally supported. Nothing stops the machine taking over ...

    In Perl, there is an excellent set of modules written by Sergey Kolychev under AI::MXNet based on Apache's MXNet. Note that it is active and very recently updated: Feb 23, 2019 !!! That's a good sign.

    My cpu and I have spent a lot of cycles trying to install the pre-requisite libraries of Apache's MXNet written in C/C++ and offering also CUDA capabilities. Two hints: do not use github repo version and use Makefile (instead of that cmake).

    Now that I have it all installed (MXNet libraries, Perl module and also R package - unrelated to this post) I would like to share with you all just what size of doors this package opens by introducing a basic dataflow operating on scalars and matrices both on CPU and GPU! The very fact that this package offers, on the side, GPU capabilities within Perl makes it, in my opinion, very very promising. I can't see much offering GPU at CPAN at the moment and here we have one package which opens both GPU and Deep Learning worlds to Perl hackers. (I have no affiliation with S.Kolychev whatsoever)

    So, here is some code to get you started on implementing a pipeline to calculate e=a*b+c*d. At first these AI::MXNet::Symbol (e.g. a,b,c,d,e) will be scalars represented as 1-dimensional AI::MXNet::NDArray (which is somewhat similar to PDL's arrays):

    use strict; use warnings; use AI::MXNet qw(mx); # specify which context we want this dataflow to be executed in # for CPU use mx->cpu(0); (note, (0) does not mean cpuid or something, + it is not used) # for GPU use mx->gpu(0); (0 denotes gpu device id) my $ctx = mx->cpu(0); # create 1D arrays with values: 1, 2, 3, 4 for a b c d respectively # these are DATA my $a_data = mx->nd->array([1], ctx => $ctx); my $b_data = mx->nd->array([2], ctx => $ctx); my $c_data = mx->nd->array([3], ctx => $ctx); my $d_data = mx->nd->array([4], ctx => $ctx); # these are SYMBOLS my $a = mx->symbol->Variable('A'); my $b = mx->symbol->Variable('B'); my $c = mx->symbol->Variable('C'); my $d = mx->symbol->Variable('D'); # these is the EXPRESSION to evaluate # basically our dataflow graph (but still no data on it, just descript +ion) my $e = ($a*$b) + ($c*$d); print "e=".$e."\n"; # this is how we associate data with symbols and specify # whether we want to run this on CPU or GPU my $exe = $e->bind( ctx => $ctx, # this is how we bind data to symbols so our dataflow graph ca +n be "executed" # and a result comes out # Note: create the arrays on the same device as executing them +, i.e. context, ctx, # must be the same here and above in creating the arrays. args => {'A'=>$a_data, 'B'=>$b_data, 'C'=>$c_data, 'D'=>$d_data} ); # propage inputs to the output(s) $exe->forward(1); # we need the first (and only one at this case) output as PDL array print "output: ".$exe->outputs->[0]->aspdl."\n";

    And this is the result:

    output: [14]

    Now, let's replace 1-dimensional data with 2x2 arrays! Just create your data as thus:

    # 2d array data, initialised to these rows (edit: updated to specify c +tx too) my $a_data = mx->nd->array([[1,2],[3,4]], ctx => $ctx); my $b_data = mx->nd->array([[5,6],[7,8]], ctx => $ctx); my $c_data = mx->nd->array([[9,10],[11,12]], ctx => $ctx); my $d_data = mx->nd->array([[13,14],[15,16]], ctx => $ctx);

    But, wait because the * operator on matrices denotes element-to-element multiplication and not the actual matrix multiplication. For that we use:

    my $e = $a->dot($b) + $c->dot($d);

    And the result is:

    [ [286 308] [366 396] ]

    If not evaluating ginormous matrix expressions using a Dataflow framework (which will also parallelise when parallelisation is possible) was not enough we have here another huge door opening for you number crunchers and Perl hackers: the ability to do this using the GPU via CUDA! Just replace the context above with the GPU-related code. And there is light! In this way, CUDA can be used via Perl not only for doing neural network stuff but for any kind of computation which you can express in a Dataflow. For example, load two images as AI::MXNet::NDArray and multiply them on the GPU! Or do some signal processing by loading an mp3 voice file as NDArray! (this paragraph was a 5' later addition)

    One thing that does not add up is that AI::MXNet::NDArray says: "However, NDArray is row-major, unlike the PDL that is column-major.". But PDL is row-major too! So have that in mind.

    Sources+more reading:

    If that does not keep you excited over the Festivus, I don't know what will ...

    Thank you Sergey Kolychev ++

    bw, bliako

    ps. some last 5 min additions and cosmetic changes. Also note the comments in the code provided for more information.

Hacker News! Just another reinvented wheel: uni
2 direct replies — Read more / Contribute
by Anonymous Monk
on Dec 13, 2019 at 23:49
    Four years and seven weeks ago our friend Ricardo SIGNES brought forth on this network, a new program, conceived by Audrey Tang: App::Uni! For some reason a year old clone of uni, written in Go, was advertised as "Hacker News" yesterday:
    Uni: Query the Unicode database from the CLI...
    Usage of App::Uni:

    Identify a character:

     - U+020AC - EURO SIGN
    Or a string:
    uni -c h
    h - U+00068 - LATIN SMALL LETTER H
     - U+020AC - EURO SIGN
    Search description:
    uni /euro/
    ₠ - U+020A0 - EURO-CURRENCY SIGN
     - U+020AC - EURO SIGN
    Multiple words are matched individually:
    uni globe earth
    Print specific codepoints or groups of codepoints:
    uni -u 2042
    ⁂ - U+02042 - ASTERISM
    uni -u 2042 2043 2044
    ⁂ - U+02042 - ASTERISM
    ⁃ - U+02043 - HYPHEN BULLET
    ⁄ - U+02044 - FRACTION SLASH
    AFAIK App::Uni does not have the -race (I mean -tone) or -gender switches of the Go uni so there was some innovation I guess.

    Anyway my meditation consists of encouraging Perl programmers to announce their wares on Hacker News, and other such websites.

Add your Meditation
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others studying the Monastery: (3)
    As of 2020-02-17 03:06 GMT
    Find Nodes?
      Voting Booth?
      What numbers are you going to focus on primarily in 2020?

      Results (70 votes). Check out past polls.