Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README Improvements #1

Open
Symbolics opened this issue Oct 27, 2019 · 11 comments
Open

README Improvements #1

Symbolics opened this issue Oct 27, 2019 · 11 comments
Assignees
Labels
enhancement New feature or request

Comments

@Symbolics
Copy link

I found this in my search for common lisp CFFI bindings to Boost mathematical libraries. On the surface this seems related, but I can't be sure. Perhaps a bit more explanation in the README, and a note about how this would be used for a binding?

@Islam0mar
Copy link
Owner

Islam0mar commented Dec 27, 2019

@Symbolics
I think this is what you need: cl-cxx-eigen

You can use the same way to add boost functions.

Sorry for the late response as I was traveling for 2 months.

@Islam0mar Islam0mar self-assigned this Dec 27, 2019
@Islam0mar Islam0mar added the help wanted Extra attention is needed label Dec 27, 2019
@Symbolics
Copy link
Author

This looks like it has a lot of potential. Is this an experiment or proof of concept, or have you been able to use it to wrap a large library. On the surface it seems to solve a lot of the problems encountered in wrapping lisp, as many libraries seem to be written exclusively in C++ these days.

@Islam0mar
Copy link
Owner

I think it has no problem to wrap large library such as eigen lib.

#include <clcxx/clcxx.hpp>
#include <string>
#include "clcxx_eigen.hpp"

CLCXX_PACKAGE EIGEN(clcxx::Package& pack) {
  using EigenMat = EigenMatWrapper<Eigen::MatrixXd, double>;

  pack.defclass<EigenMat, true>("Matrix")
      .constructor<Eigen::Index, Eigen::Index>()
      .defmethod("m.resize",
                 static_cast<void (EigenMat::*)(Eigen::Index, Eigen::Index)>(
                     &EigenMat::resize))
      .defmethod("m.block", &EigenMat::getBlock)
      .defmethod("m.row", &EigenMat::getRow)
      .defmethod("m.col", &EigenMat::getCol)
      .defmethod("m.size", &EigenMat::size)
      .defmethod("m.rows", &EigenMat::rows)
      .defmethod("m.cols", &EigenMat::cols)
      .defmethod("m.get-at-index", &EigenMat::get)
      .defmethod(
          "m.set-at-index",
          static_cast<void (EigenMat::*)(Eigen::Index, Eigen::Index, double)>(
              &EigenMat::set))
      .defmethod(
          "m.set-matrix",
          static_cast<void (EigenMat::*)(const EigenMat&)>(&EigenMat::set))
      .defmethod("m.set-zero", &EigenMat::set0)
      .defmethod("m.set-ones", &EigenMat::set1)
      .defmethod("m.set-identity", &EigenMat::setId)
      .defmethod("%m.set-from-array", &EigenMat::setFromArray)
      .defmethod("m.trace", &EigenMat::trace)
      .defmethod("m.sum", &EigenMat::sum)
      .defmethod("m.prod", &EigenMat::prod)
      .defmethod("m.mean", &EigenMat::mean)
      .defmethod("m.norm", &EigenMat::norm)
      .defmethod("m.squared-norm", &EigenMat::squaredNorm)
      .defmethod("m.print", &EigenMat::print)
      .defmethod("m.scale", &EigenMat::scale)
      .defmethod("m.add-scalar",
                 static_cast<void (EigenMat::*)(const double&)>(&EigenMat::add))
      .defmethod("m.add-mat", static_cast<void (EigenMat::*)(const EigenMat&)>(
                                  &EigenMat::add))
      .defmethod("m.multiply", &EigenMat::multiply)
      .defmethod("m.inverse", &EigenMat::inv)
      .defmethod("m.full-inverse", &EigenMat::mInv)
      .defmethod("m.transpose", &EigenMat::trans)
      .defmethod("m.determinant", &EigenMat::det)
      .defmethod("m.full-determinant", &EigenMat::mDet)
      .defmethod("m.rank", &EigenMat::rankLU)
      .defmethod("m.full-q", &EigenMat::mQ)
      .defmethod("m.full-p", &EigenMat::mP)
      .defmethod("m.p", &EigenMat::squareMP)
      .defmethod("m.l", &EigenMat::squareML)
      .defmethod("m.u", &EigenMat::squareMU)
      .defmethod("m.lower-Cholesky", &EigenMat::mLCholesky)
      .defmethod("m.upper-Cholesky", &EigenMat::mUCholesky)
      .defmethod("m.eigen-values", &EigenMat::eigenVals)
      .defmethod("m.full-solve", &EigenMat::solveLU)
      .defmethod("m.solve", &EigenMat::solveSquareLU)
      .defmethod("m.solve-Cholesky", &EigenMat::solveCholesky)
      .defmethod("m.full-lower", &EigenMat::mU)
      .defmethod("m.full-upper", &EigenMat::mL);

  pack.defun("m*", [](const EigenMat& x, const EigenMat& y) -> EigenMat {
    return static_cast<EigenMat>(x * y);
  });
  pack.defun("m+", [](const EigenMat& x, const EigenMat& y) -> EigenMat {
    return static_cast<EigenMat>(x + y);
  });
}

eigen

for my work it was acceptable.

Try to wrap your large library.

@Symbolics
Copy link
Author

Pull request #4 will also bring in some documentation improvements, though I think more documentation is required than I have knowledge to write.

@Islam0mar
Copy link
Owner

Could you specify the documentation parts that would be added?

@Islam0mar Islam0mar reopened this Feb 18, 2020
@Islam0mar Islam0mar added enhancement New feature or request and removed help wanted Extra attention is needed labels Feb 18, 2020
@Symbolics
Copy link
Author

I would suggest a few sections:

Introduction - Explain where the concepts were taken from, (Julia), high level description of how it works. limitation
Architecture - Block diagram, sequence diagrams for the calls from Lisp to C++
Examples - 2 or 3 end to end examples, with extensive documentation
Future Direction - What is planned next, if anything. E.g. Auto-wrap style wrapping so you can point to a header. Roadmap for the C++ features that are missing.
Help Wanted - what can contributors help with, by skill level.

cl-cuda and cl-autowrap have pretty good documentation and would be useful as a guide.

You might also consider contacting rpav to see if this could somehow be folded into cl-autowrap.

@ormf
Copy link

ormf commented Feb 5, 2023

The example of cl-cxx doesn't show how to instantiate classes, set slots and use class methods. Could you specify how this is done? I need this for a port to link and it'd be amazing if I could get it working (the lib already compiles...)!

The following code doesn't work here after loading the compiled lib from the example into lisp:

(cxx:add-package "TEST" "TEST") ;;; ok so far

(defparameter *test* (make-instance 'test::xx)) ;;; ok, but the CXX-CLASS-PTR slot of *test* is NIL

(setf (slot-value *test* 'test::y 32)) ;;; works

(test::foo *test*) ;;; doesn't work:
-> The value
  NIL
is not of type
  SB-SYS:SYSTEM-AREA-POINTER
when binding SB-ALIEN::VALUE

@Islam0mar
Copy link
Owner

To load a C++ class you have to call it's constructor function that is exposed from C++pack.defclass<xx, false>("xx").constructor<int, int>(), so in this example it would be called test:create-xx2 -> (test:create-xx2 1 3).

Now (make-instance 'test::xx) should give you an error message to call c++ constructor function.

@ormf ormf mentioned this issue Feb 11, 2023
@ormf
Copy link

ormf commented Feb 12, 2023

I forked your repository, created a new branch "documentation-added", added an extensive README and a working full example. I'm going to add more examples in scratch.lisp but basically it should be done. Before issuing a merge request I'd like to get your opinion, suggestions, etc.

I added the README in a new doc folder. It's completely rewritten according to the suggestions of @Symbolics . Feel free to merge with your own README, replace it or leave it in the doc folder, pointing to it or whatever. Hope you like it. It's my attempt at thanking you for your help and work, expecially in the recent week!!!

@Islam0mar
Copy link
Owner

Thanks a bunch. looks great.

@Islam0mar
Copy link
Owner

@ormf Could you please open a PR from your fork?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants