[cmucl-ticket] Re: #7: Bug in read-vector
cmucl
cmucl-devel at common-lisp.net
Sun Aug 20 03:02:12 UTC 2006
#7: Bug in read-vector
--------------------------+-------------------------------------------------
Reporter: jcunningham | Owner: somebody
Type: defect | Status: new
Priority: major | Milestone:
Component: Core | Version: 19c
Resolution: | Keywords: read-vector
--------------------------+-------------------------------------------------
Old description:
> I have been trying to read large binary files of floating point data
> using CMUCL (19c). I thought I would have to do it using some form of
> FFI and went to comp.lang.lisp for help getting that working. I
> succeeded. But Duane Rettig at Allegro suggested it would be easier to
> use 'read-vector. So I tried that as follows:
>
> (let ((vec (make-array 10 :element-type 'double-float)))
> (with-open-file (os "d10.bin")
> (read-vector vec os)
> (print vec)))
>
> where "d10.bin" is a double-float binary file containing 10
> elements. When I try to read the file it produces the following error:
>
> Type-error in KERNEL::OBJECT-NOT-DOUBLE-FLOAT-ERROR-HANDLER:
> #\Null is not of type DOUBLE-FLOAT
>
> Here is the C-code code I used to produce the file:
>
> #include <iostream>
> #include <fstream>
> #include <complex>
> using namespace std;
> int main()
> {
> int n=10;
> double *d = new double[n];
> for (int i=0; i<n; i++)
> d[i] = i;
> FILE *of = fopen("d10.bin", "wb");
> fwrite(f,8,n,of);
> fclose(of);
> return 0;
> }
>
> Here is Duane's sample code that he says works in Allegro along with
> comments:
> (copied from
> <http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/67876101085aee82/05a20cfcd11f8fbe?hl=en#05a20cfcd11f8fbe>)
> ...................................................................
> "You must be using a simple-streams implementation from another lisp.
> Allegro CL doesn't have a KERNEL package.
>
> What you're seeing above is a bug; you should report it to that
> lisp's support team.
>
> It works fine in Allegro CL (for which you can download the Express
> Edition for free):
>
> [edited formating for readability on Trac - jkc]
> (defvar *x*
> (make-array 10 :element-type 'double-float
> :initial-contents
> (loop for i from 0.0d0 to 9.0d0 collect i)))
>
> #(0.0d0 1.0d0 2.0d0 3.0d0 4.0d0 5.0d0 6.0d0 7.0d0 8.0d0 9.0d0)
>
> (with-open-file (s "z.dat" :direction :io
> :if-exists :overwrite
> :if-does-not-exist :create)
> (write-vector *x* s))
> 80
> (defvar *y* (make-array 10 :element-type 'double-float :initial-element
> 10.0d0))
>
> (with-open-file (s "z.dat")
> (read-vector *y* s))
>
> *y*
> #(0.0d0 1.0d0 2.0d0 3.0d0 4.0d0 5.0d0 6.0d0 7.0d0 8.0d0 9.0d0)
>
> --
> Duane Rettig"
>
> Further correspondence with Raymond Toy corroborates this is a bug:
>
> "Yes, this does appear to be a bug in the implementation of
> read-vector.
>
> You can, however, achieve what you want by opening the file with an
> element-type of, say, (unsigned-byte 8), instead of the default
> 'character.
>
> I'll have to read some more to understand how read-vector interacts
> with the stream element type. It seems, though, that the element-type
> of the vector overrides the element-type of the stream, more or less.
> Currently, a stream element type of character basically causes the
> code to read in characters.
>
> Ray"
>
> If you need more information, let me know and I'll see what I can do.
>
> -jeff
New description:
I have been trying to read large binary files of floating point data
using CMUCL (19c). I thought I would have to do it using some form of
FFI and went to comp.lang.lisp for help getting that working. I
succeeded. But Duane Rettig at Allegro suggested it would be easier to
use 'read-vector. So I tried that as follows:
{{{
(let ((vec (make-array 10 :element-type 'double-float)))
(with-open-file (os "d10.bin")
(read-vector vec os)
(print vec)))
}}}
where "d10.bin" is a double-float binary file containing 10
elements. When I try to read the file it produces the following error:
Type-error in KERNEL::OBJECT-NOT-DOUBLE-FLOAT-ERROR-HANDLER:
#\Null is not of type DOUBLE-FLOAT
Here is the C-code code I used to produce the file:
{{{
#include <iostream>
#include <fstream>
#include <complex>
using namespace std;
int main()
{
int n=10;
double *d = new double[n];
for (int i=0; i<n; i++)
d[i] = i;
FILE *of = fopen("d10.bin", "wb");
fwrite(f,8,n,of);
fclose(of);
return 0;
}
}}}
Here is Duane's sample code that he says works in Allegro along with
comments:
(copied from
<http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/67876101085aee82/05a20cfcd11f8fbe?hl=en#05a20cfcd11f8fbe>)
...................................................................
"You must be using a simple-streams implementation from another lisp.
Allegro CL doesn't have a KERNEL package.
What you're seeing above is a bug; you should report it to that
lisp's support team.
It works fine in Allegro CL (for which you can download the Express
Edition for free):
[edited formating for readability on Trac - jkc]
{{{
(defvar *x*
(make-array 10 :element-type 'double-float
:initial-contents
(loop for i from 0.0d0 to 9.0d0 collect i)))
#(0.0d0 1.0d0 2.0d0 3.0d0 4.0d0 5.0d0 6.0d0 7.0d0 8.0d0 9.0d0)
(with-open-file (s "z.dat" :direction :io
:if-exists :overwrite
:if-does-not-exist :create)
(write-vector *x* s))
80
(defvar *y* (make-array 10 :element-type 'double-float :initial-element
10.0d0))
(with-open-file (s "z.dat")
(read-vector *y* s))
*y*
#(0.0d0 1.0d0 2.0d0 3.0d0 4.0d0 5.0d0 6.0d0 7.0d0 8.0d0 9.0d0)
}}}
--
Duane Rettig"
Further correspondence with Raymond Toy corroborates this is a bug:
"Yes, this does appear to be a bug in the implementation of
read-vector.
You can, however, achieve what you want by opening the file with an
element-type of, say, (unsigned-byte 8), instead of the default
'character.
I'll have to read some more to understand how read-vector interacts
with the stream element type. It seems, though, that the element-type
of the vector overrides the element-type of the stream, more or less.
Currently, a stream element type of character basically causes the
code to read in characters.
Ray"
If you need more information, let me know and I'll see what I can do.
-jeff
Comment (by rtoy):
First I added a bit of markup so that the code bits are formatted better.
Now for the bug report, there are a couple of issues here. CMUCL has an
extension, READ-VECTOR, which is similar to the SIMPLE-STREAM's READ-
VECTOR, but not quite. In particular, it produces the bug that you see.
However, if you {{{(require 'simple-streams)}}}, READ-VECTOR will be
replaced with the simple-stream version. Then, the following snip of code
works as Duane mentions:
{{{
(let ((vec (make-array 10 :element-type 'double-float)))
(with-open-file (os "d10.bin" :class 'stream:file-simple-
stream)
(stream:read-vector vec os) (print vec)))
}}}
The important part is that you open the file with the appropriate class.
Not sure what to do. We can change READ-VECTOR to match simple-stream
READ-VECTOR.
(BTW, READ-VECTOR is much faster than STREAM:READ-VECTOR.)
--
Ticket URL: <http://trac.common-lisp.net/cmucl/ticket/7>
cmucl <http://common-lisp.net/project/cmucl>
cmucl
More information about the cmucl-ticket
mailing list