【问题标题】:Code runs in SLIME+SBCL but not plain SBCL代码在 SLIME+SBCL 中运行,但不是普通的 SBCL
【发布时间】:2013-10-18 19:54:59
【问题描述】:

我一直在尝试为 CFFI 绑定 (https://gitorious.org/dh-misc/hdf5/source/cb616fd619a387e3cdc927994b9ad12b6b514236:) 构建一个 lispy 接口,但我遇到了这样一种情况,即代码在 SLIME 中正确运行,它有一个 SBCL 实例作为后端,但不会在任何时候运行我只在 SBCL 中运行代码。

所以,我创建了一个演示错误的测试用例文件:

(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)))))

我在 SLIME+SBCL 中运行 (hdf5test:test "test.h5") 得到的输出是

dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
0

我在 SBCL 中运行 (hdf5test:test "test.h5") 得到的输出是

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

所以你可以看到这与数组如何传递给 hdf 函数有关,但我不知道为什么 SLIME+SBCL 会处理这个问题而不是 SBCL。

我也用 CLISP 尝试了完全相同的代码,它工作正常,没有问题,所以这似乎是一个 SBCL 问题。

对此有什么想法吗?

编辑:我想我应该在主帖中添加结果文件在每种情况下确实不同。在 SLIME+SBCL 或 CLISP 中,该文件包含一个有限数据集,其中包含平方整数(实际上没有任何原因,只是一个测试)。但是,对于普通的 SBCL,数据文件是不完整的;如果您尝试使用 h5dump 查看内容,这是一次无休止的零试验(这就是它处理不完整数据集的方式)。

【问题讨论】:

  • “奔跑”是什么意思?如何在 SLIME/SBCL 和 SBCl 下编译运行代码?
  • 在 SLIME+SBCL 中,我要么使用 (load ...) 函数直接在 slime REPL 中加载,要么使用 C-c C-l emacs 快捷方式将文件加载到列表图像中。在 SBCL 下,我使用 (load ...) 函数或使用 --load 选项运行 sbcl。要运行,我只需在 REPL 中执行 (hdf5test:test "test.h5")。
  • 顺便说一句,此代码确实需要安装 HDF5 C 库才能运行。
  • 我没有进入调试器,但结果确实不同。在 SLIME+SBCL 或 CLISP 中,生成的文件应该包含有意义的数据。但是,仅使用 SBCL,数据文件不正确,没有有意义的数据。因此,处理代码的方式似乎确实有所不同。 SLIME 对环境有影响吗?
  • 我最近遇到了类似的情况,其中我(忘记了我)在 Slime 中调用 SBCL,其中保存的核心文件正在初始化我使用的一些库,然后以不同的方式加载(不同的初始化调用)来自外壳。您是否可能将 args 传递给 inferior-lisp 或类似的 SBCL?

标签: common-lisp hdf5 sbcl slime cffi


【解决方案1】:

就像@nixeagle 所说,slime 似乎隐藏了源自 hdf5 库的错误消息。按照这些思路,我敢打赌,将结果从 SBCL 传递给 slime 中的 emacs 是允许写入文件的原因。

现在需要用一些盐来处理以下内容,因为我对 hdf5 或 cffi 真的一无所知,现在刚刚回到普通的 lisp 中,但是在 slime 和 sbcl 上,事情开始始终如一我的 x86_64 linux 机器,一旦我用 :uint64 替换了所有这些 :int 类型,这似乎是有道理的,因为无论如何声明都解析为该类型。

您在 sbcl 中的代码:

* (load "temp.lisp")
T
* (hdf5test:test "test2.h5")
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
HDF5-DIAG: Error detected in HDF5 (1.8.12) 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.12) thread 0:
  #000: H5Dio.c line 231 in H5Dwrite(): can't prepare for writing data
    major: Dataset
    minor: Write failed
  #001: H5Dio.c line 332 in H5D__pre_write(): not a data space
    major: Invalid arguments to routine
    minor: Inappropriate type
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
  #000: H5S.c line 405 in H5Sclose(): not a dataspace
    major: Invalid arguments to routine
    minor: Inappropriate type
0

部分改动:

    (with-foreign-objects ((dim :uint64 1)
               (dataspace-maxdim :uint64 1)
               (memspace-maxdim :uint64 1)
               (chunkdim :uint64 1)
               (dataspace 'hid-t)
               (dataset 'hid-t)
               (memspace 'hid-t)
               (cparms 'hid-t))
      (setf (mem-aref dim :uint64 0) 5)
      (format t "dim: ~a~%" (mem-aref dim :uint64 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 :uint64 0) 1)
      (format t "dataspace-maxdim: ~a~%" (mem-aref dataspace-maxdim :uint64 0))
      (format t "memspace-maxdim: ~a~%" (mem-aref memspace-maxdim :uint64 0))

在 sbcl 中更改代码:

* (load "temp.lisp")
T
* (hdf5test:test "test2.h5")
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
0

结果文件:

% h5dump test.h5 
HDF5 "test.h5" {
GROUP "/" {
   DATASET "dataset" {
      DATATYPE  H5T_STD_I32LE
      DATASPACE  SIMPLE { ( 5 ) / ( H5S_UNLIMITED ) }
      DATA {
      (0): 0, 1, 4, 9, 16
      }
   }
}
}
% h5dump test2.h5
HDF5 "test2.h5" {
GROUP "/" {
   DATASET "dataset" {
      DATATYPE  H5T_STD_I32LE
      DATASPACE  SIMPLE { ( 5 ) / ( H5S_UNLIMITED ) }
      DATA {
      (0): 0, 1, 4, 9, 16
      }
   }
}
}

【讨论】:

  • 刚刚检查了您的解决方案,它也适用于我的机器!
  • 我不知道为什么 SBCL 而不是 SLIME+SBCL 或 CLISP 会失败,但我可以确认 :int 的暗淡变量实际上是错误的,所以为什么不同的实现处理可能并不重要错误的代码不同。
猜你喜欢
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
  • 2016-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多