pytorchclojurescriptclojurescript-javascript-interop

How to use js-pytorch with clojurescript on MacOS?


Using js-pytorch with clojurescript unsuccessfully. Please comment how to fix the installation issue of js-pytorch with clojurescript

execute in calva-repl:

(ns server.ros2
  (:require ["js-pytorch" :as torch])) => nil

(def device "gpu") => #'server.ros2/device

execute in calva-repl:

(torch/randn #js [8 4 5]) => :repl/exception!

; Execution error (TypeError) at (<cljs repl>:1).
; module$node_modules$js_pytorch$dist$index_cjs.randn is 
not a function. (In module$node_modules$js_pytorch$dist
$index_cjs.randn([(8),(4),(5)])',  'module$node_modules
$js_pytorch$dist$index_cjs.randn' is undefined)
 

deps.edn:

{:paths ["src"]
 :aliases {:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.28.16"}}}
           :outdated {;; Note that it is `:deps`, not `:extra-deps`
                      :deps {com.github.liquidz/antq {:mvn/version "RELEASE"}}
                      :main-opts ["-m" "antq.core"]}}
 :deps {reagent/reagent {:mvn/version "1.2.0"}}}

Shadown-cljs.edn:

 {:deps {:aliases [:cljs]}
 :builds {:app {:target :browser
                :output-dir "public/js"
                :asset-path "/js"
                :modules {:main {:init-fn client.core/init}}}
          :server {:target :node-script
                   :output-to "out/server.js"
                   :main server.core/start}}
 :dev-http {8080 "public"}}

package.json

{
  "name": "cljs-express-htmx",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "create-react-class": "^15.7.0",
    "express": "^4.19.2",
    "js-pytorch": "^0.6.0",
    "rclnodejs": "^0.27.4",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "shadow-cljs": "^2.28.16"
  }
}

Installed js-pytorch with bun:

bun init 
bun add js-pytorch

Using js-pytorch with clojurescript

   (ns server.ros2
      (:require ["js-pytorch" :as torch]))
    
    (defn example []
        ;; Pass device as an argument to a Tensor or nn.Module
      (let [device "gpu"]
    
          ;; Instantiate Tensors
        (let [x (torch/randn #js [8 4 5])
              w (torch/randn #js [8 5 4] true device)
              b (torch/tensor #js [0.2 0.5 0.1 0.0] true)]
    
            ;; Make calculations
          (let [out (-> (torch/matmul x w)
                        (torch/add b))]
    
              ;; Compute gradients on the whole graph
            (.backward out)
    
              ;; Get gradients from specific Tensors
            (js/console.log (.-grad w))
            (js/console.log (.-grad b))))))

Solution

  • This is the example used in the js-pytorch README.

    const { torch } = require("js-pytorch");
    

    This does not translate to the ns :require you have. Instead it translates to

    (ns server.ros2
      (:require ["js-pytorch" :refer (torch)]))
    

    then using (.randn torch ...) and so on.

    OR, alternatively since the syntax will be a bit nicer using / like your code does you can do

    (ns server.ros2
      (:require ["js-pytorch$torch" :as torch]))
    

    This basically just sets up torch as the namespace alias, allowing the use of torch/randn and so on.

    See the translation examples in the shadow-cljs User Guide.