MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Read/Write streams in parallel

  • To: mathgroup at smc.vnet.net
  • Subject: [mg109841] Read/Write streams in parallel
  • From: ChrisL <chris.ladroue at gmail.com>
  • Date: Wed, 19 May 2010 20:13:35 -0400 (EDT)

For a future project, I'll need to read and write some streams in
parallel. I've started playing with a simple example and can't make it
work.
What I want to do is to read an entry from a stream ('testfile') and
write its value to another stream ('testfile2'). This is
straightforward with one processor but in parallel, I get either a
wrong result or errors messages.
For example (testfile contains the first 100 prime numbers):
ParallelEvaluate[sr = OpenRead@FileNameJoin[{$TemporaryDirectory,
"testfile"}]]
ParallelEvaluate[wr = OpenAppend@FileNameJoin[{$TemporaryDirectory,
"testfile2"}]]
ParallelDo[
	x = Read[sr]; Print[{x, $KernelID}];
	Write[wr, {x, $KernelID}], {10}];
ParallelEvaluate[Close[sr]]
ParallelEvaluate[Close[wr]]

testfile2 then contains:
{2, 2}
{2, 1}
{3, 2}
{3, 1}
{5, 2}
{5, 1}
{7, 2}
{7, 1}
{11, 2}
{11, 1}
This is not satisfactory: the entries are read twice, once per
processor. Obviously, it's because the two streams are opened by both
processors in parallel. So we want the streams to be opened only once,
and their 'pointers' (location of last entry read) to be updated
concurrently.
I try this instead:
sr = OpenRead@FileNameJoin[{$TemporaryDirectory, "testfile"}]
wr = OpenAppend@FileNameJoin[{$TemporaryDirectory, "testfile2"}]
SetSharedVariable[sr, wr]
ParallelDo[x = Read[sr]; Print[{x, $KernelID}];
  Write[wr, {x, $KernelID}], {4}];
Close[sr]
Close[wr]

This time the two streams should be open only once and sync-ed thanks
to SetSharedVariable. But testfile2 ends up being empty*, and
Mathematica sends some error messages:
InputStream["/tmp/testfile", 33]  	(* Value of sr *)
OutputStream["/tmp/testfile2", 34]  (* Value of wr *)
(kernel 2) Read::openx: InputStream[/tmp/testfile,33] is not open. (*
yes it is! *)
(kernel 1) Read::openx: InputStream[/tmp/testfile,33] is not open. (*
yes it is! *)
etc.

Is there any way I can make it work? The correct content for testfile2
should be the list of the 10 first prime numbers, possibly in a
different order, and the kernelID that wrote the entry.

* if it starts from an empty file. Notice the OpenAppend (!=OpenWrite)
Thank you very much in advance,
Cheers,
Chris


  • Prev by Date: Re: How to Enable Automatic Recalculation
  • Next by Date: Re: Latex, Mathematica, and journals
  • Previous by thread: Re: Equals, Less, Greater, etc; Confused by this simple
  • Next by thread: Re: Read/Write streams in parallel