caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Thomas Fischbacher <tf@functionality.de>
To: Xavier Leroy <Xavier.Leroy@inria.fr>
Cc: Caml-list List <caml-list@inria.fr>
Subject: Re: [Caml-list] Bigarray question
Date: Mon, 28 Jan 2008 12:57:47 +0000	[thread overview]
Message-ID: <479DD14B.2030209@functionality.de> (raw)
In-Reply-To: <47695924.8090202@inria.fr>

Xavier Leroy wrote:

(on whether it is permissible to dynamically change the dim and data
pointers in a ML bigarray):

>>as far as I can tell, it is easy (but not explicitly allowed in the
>>documentation) to allocate a Caml bigarray and change the data
>>pointer inside that bigarray afterwards.
>>There is no problem in implementing this, technically speaking.
>>But this would require a change to the ML documentation stating
>>that it is explicitly considered as permissible to change the
>>data pointer in a bigarray. Can I get that, please?
> 
> 
> I see no reason why this would cause problems, as long as the data
> pointer points to C data of the right shape and dimensions.  (Of
> course, you could update the dimensions of the bigarray as
> appropriate, if needed.)  I don't think I would document this, as I
> wouldn't quite know how to word it in the docs, but you have my
> encouragements to try and report problems if any.


As a matter of fact, considering the two C functions below which I use
in our "nsim" abstract field theory/multiphysics simulation engine to
speed up some internal computation, the first variant would be desirable
but crashes. The second works. What this actually is about is to
systematically go through the rows of a sparse matrix, handled by the
PETSc library. (So, basically, I am using a sparse matrix as sort-of a
hash of row index to entries here.)

CAMLprim value caml_petsc_matrix_call_on_rows_raw(value ml_mx,
						  value ml_fun,
						  value ml_start_row,
						  value ml_end_row
						  )
{
   CAMLparam4(ml_mx,ml_fun,ml_start_row,ml_end_row);
   Mat mx;
   int start_row,end_row,start_own,end_own;
   int i,ncols=0;
   const int *cols=0;
   const PetscScalar *vals=0;
   CAMLlocal2(ba_indices,ba_vals);

   petsc_checkinit();
   petsc_check_mat(ml_mx);

   mx=(Mat)Field(ml_mx,1);

   MatGetOwnershipRange(mx,&start_own,&end_own);

   start_row=Int_val(ml_start_row);
   end_row=Int_val(ml_end_row);

   if(start_row == -1)start_row=start_own;
   if(end_row == -1)end_row=end_own;

   /* We would like to do things this way, but while one may guess that 
it should work,
      this (1) is not covered by what is permitted according to the 
OCaml documentation,
      and (2) indeed produces crashes.
   */
   ba_indices=alloc_bigarray_dims(BIGARRAY_NATIVE_INT | BIGARRAY_C_LAYOUT,
				 1, cols, ncols);

   ba_vals=alloc_bigarray_dims(BIGARRAY_FLOAT64 | BIGARRAY_C_LAYOUT,
			      1, vals, ncols);


   for(i=start_row;i<end_row;i++)
     {
       MatGetRow(mx,i,&ncols,&cols,&vals);

       Bigarray_val(ba_indices)->dim[0]=ncols;
       Bigarray_val(ba_vals)->dim[0]=ncols;

       Bigarray_val(ba_indices)->data=(void*)cols;
       Bigarray_val(ba_vals)->data=(void*)vals;

       callback3(ml_fun,Val_int(i),ba_indices,ba_vals);

       MatRestoreRow(mx,i,&ncols,&cols,&vals);
     }

   CAMLreturn(Val_unit);
}



CAMLprim value caml_petsc_matrix_call_on_rows_raw_defensive(value ml_mx,
							    value ml_fun,
							    value ml_start_row,
							    value ml_end_row
							    )
{
   CAMLparam4(ml_mx,ml_fun,ml_start_row,ml_end_row);
   Mat mx;
   int start_row,end_row,start_own,end_own;
   int i,ncols=0;
   const int *cols=0;
   const PetscScalar *vals=0;
   CAMLlocal2(ba_indices,ba_vals);

   petsc_checkinit();
   petsc_check_mat(ml_mx);

   mx=(Mat)Field(ml_mx,1);

   MatGetOwnershipRange(mx,&start_own,&end_own);

   start_row=Int_val(ml_start_row);
   end_row=Int_val(ml_end_row);

   if(start_row == -1)start_row=start_own;
   if(end_row == -1)end_row=end_own;


   for(i=start_row;i<end_row;i++)
     {
       MatGetRow(mx,i,&ncols,&cols,&vals);

       ba_indices=alloc_bigarray_dims(BIGARRAY_NATIVE_INT | 
BIGARRAY_C_LAYOUT,
				     1, cols, ncols);

       ba_vals=alloc_bigarray_dims(BIGARRAY_FLOAT64 | BIGARRAY_C_LAYOUT,
				  1, vals, ncols);

       callback3(ml_fun,Val_int(i),ba_indices,ba_vals);

       MatRestoreRow(mx,i,&ncols,&cols,&vals);
     }

   CAMLreturn(Val_unit);
}


-- 
best regards,
Thomas Fischbacher
tf@functionality.de


  parent reply	other threads:[~2008-01-28 12:48 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-18 17:44 Thomas Fischbacher
2007-12-19 17:47 ` [Caml-list] " Xavier Leroy
2007-12-19 19:15   ` Thomas Fischbacher
2008-01-28 12:57   ` Thomas Fischbacher [this message]
  -- strict thread matches above, loose matches on Subject: below --
2005-11-25 18:19 Thomas Fischbacher
2005-11-25 20:06 ` [Caml-list] " Dmitry Bely
2005-11-27 22:48   ` Thomas Fischbacher
2005-11-28  9:39     ` Dmitry Bely
2005-11-28 21:30       ` Thomas Fischbacher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=479DD14B.2030209@functionality.de \
    --to=tf@functionality.de \
    --cc=Xavier.Leroy@inria.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).