Ho cercato di creare un'interfaccia lispy per i collegamenti CFFI (https://gitorious.org/dh-misc/hdf5/source/cb616fd619a387e3cdc927994b9ad12b6b514236 :), ma mi sono imbattuto in una situazione in cui il codice viene eseguito correttamente in SLIME che ha un'istanza SBCL come backend, ma non verrà eseguito ogni volta che eseguirò il codice solo in SBCL.Il codice viene eseguito in SLIME + SBCL ma non è semplice SBCL
Così, ho creato un fascicolo di prova che dimostra l'errore:
(asdf:load-system :cffi)
;;(asdf:operate 'asdf:load-op :cffi)
(defpackage :hdf5test
(:use :cl :cffi)
(:export :test))
(in-package :hdf5test)
(define-foreign-library hdf5
(t (:default "libhdf5")))
(use-foreign-library hdf5)
;; hdf types:
(defctype size-t :uint)
(defctype hid-t :int)
(defctype herr-t :int)
(defctype hsize-t :uint64)
;; hdf constants:
;; H5S_UNLIMITED: 2^64-1
(defconstant +H5S-UNLIMITED+ 18446744073709551615)
;; H5F_ACC_TRUNC
(defconstant +H5F-ACC-TRUNC+ 2) ;; we'll see if it works
;; H5P_DEFAULT
(defconstant +H5P-DEFAULT+ 0)
;; H5T types:
(defconstant +H5P-DATASET-CREATE+ 150994953)
(defconstant +H5T-NATIVE-INT+ 50331660)
;; hdf functions:
;; H5Screate_simple
(defcfun "H5Screate_simple" hid-t
(rank :int)
(current-dims :pointer) ; const hsize_t*
(maximum-dims :pointer)) ; cons hsize_t*
;; H5Fcreate
(defcfun "H5Fcreate" hid-t
(filename :string)
(flags :uint)
(fcpl-id hid-t)
(fapl-id hid-t))
;; H5Pcreate
(defcfun "H5Pcreate" hid-t
(cls-id hid-t))
;; H5Pset_chunk
(defcfun "H5Pset_chunk" herr-t
(plist hid-t)
(ndims :int)
(dim :pointer)) ;; const hsize_t*
;; H5Pset_deflate
(defcfun "H5Pset_deflate" herr-t
(plist-id hid-t)
(level :uint))
;; H5Dcreate1
(defcfun "H5Dcreate1" hid-t
(loc-id hid-t)
(name :string)
(type-id hid-t)
(space-id hid-t)
(dcpl-id hid-t))
;; H5Dclose
(defcfun "H5Dclose" herr-t
(dataset-id hid-t))
;; H5Dwrite
(defcfun "H5Dwrite" herr-t
(datset-id hid-t)
(mem-type-id hid-t)
(mem-space-id hid-t)
(file-space-id hid-t)
(xfer-plist-id hid-t)
(buf :pointer))
;; H5Fclose
(defcfun "H5Fclose" herr-t
(file-id hid-t))
;; H5Sclose
(defcfun "H5Sclose" herr-t
(space-id hid-t))
(defparameter *rank* 1)
(defun test (filename)
(with-foreign-string (dataset-name "dataset")
(with-foreign-objects ((dim :int 1)
(dataspace-maxdim :uint64 1)
(memspace-maxdim :uint64 1)
(chunkdim :int 1)
(dataspace 'hid-t)
(dataset 'hid-t)
(memspace 'hid-t)
(cparms 'hid-t))
(setf (mem-aref dim :int 0) 5)
(format t "dim: ~a~%" (mem-aref dim :int 0))
;;(setf (mem-aref maxdim :int 0) -1)
(setf (mem-aref dataspace-maxdim :uint64 0) +H5S-UNLIMITED+)
(setf (mem-aref memspace-maxdim :uint64 0) 5)
(setf (mem-aref chunkdim :int 0) 1)
(format t "dataspace-maxdim: ~a~%" (mem-aref dataspace-maxdim :uint64 0))
(format t "memspace-maxdim: ~a~%" (mem-aref memspace-maxdim :uint64 0))
;;(with-open-hdf-file (file filename :direction :output :if-exists :supersede)
(let ((file (h5fcreate filename +H5F-ACC-TRUNC+ +H5P-DEFAULT+ +H5P-DEFAULT+)))
(setf cparms (h5pcreate +H5P-DATASET-CREATE+))
(h5pset-chunk cparms *rank* chunkdim)
(setf dataspace (h5screate-simple *rank* dim dataspace-maxdim))
(setf dataset (h5dcreate1
file
dataset-name
+H5T-NATIVE-INT+
dataspace
cparms))
(format t "dataspace: ~a~%" dataspace)
(format t "dataset: ~a~%" dataset)
(setf memspace (h5screate-simple *rank* dim memspace-maxdim))
(with-foreign-object (data :int 5)
(loop for i from 0 to 4 do (setf (mem-aref data :int i) (* i i)))
(h5dwrite dataset +H5T-NATIVE-INT+ memspace dataspace +H5P-DEFAULT+ data))
(h5dclose dataset)
(h5sclose memspace)
(h5sclose dataspace)
(h5fclose file)))))
L'uscita che ricevo da correre (hdf5test: test "test.h5") di melma + SBCL è
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
0
L'uscita che ricevo da correre (hdf5test: test "test.h5") in soli SBCL è
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: H5S.c line 1388 in H5Screate_simple(): maxdims is smaller than dims
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: H5Dio.c line 233 in H5Dwrite(): not a data space
major: Invalid arguments to routine
minor: Inappropriate type
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: H5S.c line 405 in H5Sclose(): not a dataspace
major: Invalid arguments to routine
minor: Inappropriate type
0
Così si può vedere che è Somet ha a che fare con il modo in cui l'array viene passato alle funzioni hdf, ma non ho idea del perché SLIME + SBCL possa gestire questo ma non SBCL.
Ho anche provato lo stesso codice esatto con CLISP e funziona perfettamente, nessun problema, quindi sembra essere un problema SBCL.
Qualche idea su questo?
MODIFICA: ho pensato di aggiungere al post principale che i file risultanti sono veramente diversi in ogni caso. In SLIME + SBCL o CLISP il file contiene un set di dati finito con interi quadrati all'interno (senza motivo, solo un test). Ma con il semplice SBCL il file di dati è incompleto; se si tenta di visualizzare i contenuti con h5dump, si tratta di una prova senza fine di zero (è così che gestisce i set di dati incompleti).
cosa significa 'corre'? come si compila e si esegue il codice sotto SLIME/SBCL e SBCl? –
In SLIME + SBCL, o carico direttamente nel REPL di melma con la funzione (carica ...), oppure uso il collegamento C-c em-lc per caricare il file nell'immagine della lista. Sotto solo SBCL, utilizzo la funzione (carica ...) o eseguo sbcl con l'opzione --load. Per eseguire, faccio solo (hdf5test: test "test.h5") nel REPL. – ghollisjr
BTW questo codice richiede l'installazione di librerie C HDF5 per l'esecuzione. – ghollisjr