From 8a138e11928825c1c77ab2c5d66d38926cbc9975 Mon Sep 17 00:00:00 2001 From: Ed J Date: Thu, 24 Oct 2024 23:31:50 +0100 Subject: [PATCH] preserve badflag across threads --- Changes | 2 ++ lib/PDL/Parallel/threads.pm | 16 +++++++--------- t/30_sharing_from_threads.t | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Changes b/Changes index d79236e..ac5a5b9 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ +- preserve badflag across threads + 2024-09-06 0.06 - move XS support functions to PDL 2.091, now pure perl diff --git a/lib/PDL/Parallel/threads.pm b/lib/PDL/Parallel/threads.pm index 6a36c5e..6757793 100644 --- a/lib/PDL/Parallel/threads.pm +++ b/lib/PDL/Parallel/threads.pm @@ -30,6 +30,7 @@ my %datasv_pointers :shared; my %dataref_svs; my %dim_arrays :shared; my %types :shared; +my %badflag :shared; my %nbytes :shared; my %originating_tid :shared; my %file_names :shared; @@ -94,6 +95,7 @@ sub share_pdls { $dim_arrays{$name} = [$to_store->dims]; } $types{$name} = $to_store->get_datatype; + $badflag{$name} = $to_store->badflag; } elsif (ref($to_store) eq '') { # A file name, presumably; share via memory mapping @@ -138,6 +140,7 @@ sub free_pdls { delete $datasv_pointers{$name}; delete $dim_arrays{$name}; delete $types{$name}; + delete $badflag{$name}; delete $nbytes{$name}; delete $originating_tid{$name}; push @removed, $name; @@ -185,6 +188,7 @@ sub retrieve_pdls { # Create the new thinly wrapped ndarray my $new_ndarray = PDL->new_around_datasv($datasv_pointers{$name}); $new_ndarray->set_datatype($types{$name}); + $new_ndarray->badflag($badflag{$name}); $new_ndarray->setdims(\@{$dim_arrays{$name}}); $new_ndarray->set_donttouchdata($nbytes{$name}); # protect its memory push @to_return, $new_ndarray; @@ -489,9 +493,7 @@ collection of shared memory that you may need to use for your algorithm: =for bad -C does not pay attention to bad values. There is no technical -reason for this: it simply hadn't occurred to me until I had to write the -bad-data documentation. Expect it to happen in a forthcoming release. :-) +C preserves the badflag on ndarrays. =head2 share_as @@ -534,9 +536,7 @@ ndarray memory space. =for bad -C does not pay attention to bad values. There is no technical -reason for this: it simply hadn't occurred to me until I had to write the -bad-data documentation. Expect it to happen in a forthcoming release. :-) +C preserves the badflag on ndarrays. =head2 retrieve_pdls @@ -563,9 +563,7 @@ indicating that you probably meant to say something differently. =for bad -C does not pay attention to bad values. There is no technical -reason for this: it simply hadn't occurred to me until I had to write the -bad-data documentation. Expect it to happen in a forthcoming release. :-) +C preserves the badflag on ndarrays. =head2 free_pdls diff --git a/t/30_sharing_from_threads.t b/t/30_sharing_from_threads.t index a643fa5..234f7ce 100644 --- a/t/30_sharing_from_threads.t +++ b/t/30_sharing_from_threads.t @@ -23,12 +23,16 @@ use PDL::Parallel::threads::SIMD qw(parallelize parallel_id parallel_sync); my $N_threads = 5; my @data_is_correct : shared; my @could_get_data : shared; +my @bad_is_correct : shared; parallelize { my $pid = parallel_id; # Create data that is unique to this thread my $pdl = ones(10) * $pid; $pdl->share_as("data$pid"); + my $bad = ones(5); + $bad->setbadat(2); + $bad->share_as("bad$pid"); # We will get the data from the *previous* thread (modulo the number of # threads, of course: circular boundary conditions) @@ -49,11 +53,16 @@ parallelize { $data_is_correct[$pid] = all($to_test == $thread_to_grab)->sclr or diag("For thread $pid, expected ${thread_to_grab}s but got $to_test"); + $to_test = retrieve_pdls("bad$thread_to_grab"); + my $isbad = $to_test->isbad; + $bad_is_correct[$pid] = all($isbad == pdl(0,0,1,0,0))->sclr || diag "got=$isbad"; + 1; } or do { diag("data pull for pid $pid failed: $@"); $could_get_data[$pid] = 0; $data_is_correct[$pid] = 0; + $bad_is_correct[$pid] = 0; }; } $N_threads; @@ -65,6 +74,9 @@ is_deeply(\@could_get_data, \@expected, is_deeply(\@data_is_correct, \@expected, 'Data created by sibling threads worked correctly') or diag("expected all 1s, actually got @data_is_correct"); +is_deeply(\@bad_is_correct, \@expected, + 'Data created by sibling threads badflags survived correctly') + or diag("expected all 1s, actually got @data_is_correct"); # Make sure the retrieval causes a croak for (1..$N_threads-1) { @@ -74,6 +86,4 @@ for (1..$N_threads-1) { , "Retrieving shared data created by already-terminated thread $_ croaks"; } - - done_testing();