Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  ODP: howto Pipe (PICCA Frederic-Emmanuel)
   2. Re:  ODP: howto Pipe (Marcin Mrotek)


----------------------------------------------------------------------

Message: 1
Date: Thu, 18 Feb 2016 18:09:51 +0000
From: PICCA Frederic-Emmanuel
        <frederic-emmanuel.pi...@synchrotron-soleil.fr>
To: "The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell" <beginners@haskell.org>
Subject: Re: [Haskell-beginners] ODP: howto Pipe
Message-ID:
        
<a2a20ec3b8560d408356cac2fc148e53b303a...@sun-dag3.synchrotron-soleil.fr>
        
Content-Type: text/plain; charset="us-ascii"

Yes my withSomething method are of this kind

withGeometry ::  Factory -> Geometry -> (Ptr HklGeometry -> IO b) -> IO b
withGeometry f g fun = do
  fptr <- newGeometry f g
  withForeignPtr fptr fun

newGeometry :: Factory -> Geometry -> IO (ForeignPtr HklGeometry)


If I come back to my method, at the beginin I had this signature.

solveTraj :: Factory -> Geometry -> Detector -> Sample -> [Engine] -> IO 
[GEometry]

the last line was 

mapM (solve' engine n e >>= getSolution0) [engines]


but When I run the code for 100000 points I got a huge consomation of the 
memory...
So I tryed to solve this problem using the Pipe.

solveTraj :: Factory -> Geometry -> Detector -> Sample -> Pipe Engine Geometry 
IO ()
solveTraj f g d s = do
  e <- await
  let name = engineName e
  withSample s $ \sample ->
      withDetector d $ \detector ->
          withGeometry f g $ \geometry ->
              withEngineList f $ \engines ->
                withCString name $ \cname -> do
                  c_hkl_engine_list_init engines geometry detector sample
                  engine <- c_hkl_engine_list_engine_get_by_name engines cname 
nullPtr
                  n <- c_hkl_engine_pseudo_axis_names_get engine >>= 
darrayStringLen
                  yield $ solve' engine n e >>= getSolution0

Now I think that this is maybe the wrong way to solve my issue.

the computation done by my C library in the solve' depends of the previous step.

when I solve my system the geometry "C object" move. (this is a side effect 
really important for my computation)

solve' :: Ptr HklEngine -> CSize -> Engine -> IO (ForeignPtr HklGeometryList)
solve' engine n (Engine _ ps _) = do
  let positions = [v | (Parameter _ v _) <- ps]
  withArray positions $ \values ->
      c_hkl_engine_pseudo_axis_values_set engine values n unit nullPtr
      >>= newForeignPtr c_hkl_geometry_list_free

so I can not convert this into a single pipe step...
or maybe it is possible to create a pipe which store this internal state in 
order to treat each steps.

It start to be a little bit difficult for me to manage all this :))


Cheers

Frederic.


Ps: the starting point of this is the huge memory use by my software...

------------------------------

Message: 2
Date: Fri, 19 Feb 2016 09:05:31 +0100
From: Marcin Mrotek <marcin.jan.mro...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] ODP: howto Pipe
Message-ID:
        <CAJcfPz=TjpsMn2gREaK=Yz0f33mA6s=rtpq-zybylqbzfoq...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

Well, if pipelining only the outermost layer is enough to improve
performance of your code, perhaps you could just move `yield` outside
all the `with...` functions, so everything stays in IO until it's
ready to yield the result:

solveTraj :: Factory -> Geometry -> Detector -> Sample -> Pipe Engine
Geometry IO ()
solveTraj f g d s = do
  e <- await
  let name = engineName e
  solution <- withSample s $ \sample ->
      withDetector d $ \detector ->
          withGeometry f g $ \geometry ->
              withEngineList f $ \engines ->
                withCString name $ \cname -> do
                  c_hkl_engine_list_init engines geometry detector sample
                  engine <- c_hkl_engine_list_engine_get_by_name
engines cname nullPtr
                  n <- c_hkl_engine_pseudo_axis_names_get engine >>=
darrayStringLen
                  return $ solve' engine n e >>= getSolution0
  yield solution

This can be further simplified to use the version of `mapM` from
Pipes.Prelude 
(https://hackage.haskell.org/package/pipes-4.1.8/docs/Pipes-Prelude.html)

mapM :: Monad m => (a -> m b) -> Pipe a b m r

This way your code would look more or less like it looked without
pipes, something like:

import qualified Pipes.Prelude as Pipes

runEffect $ for (each engines) >-> Pipes.mapM (solve' engine n e >>=
getSolution0) >-> P.print

Best regards,
Marcin Mrotek


------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 92, Issue 22
*****************************************

Reply via email to