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

Datamancer works not with nimscript #70

Open
diegovskytl opened this issue Jul 14, 2024 · 1 comment
Open

Datamancer works not with nimscript #70

diegovskytl opened this issue Jul 14, 2024 · 1 comment

Comments

@diegovskytl
Copy link

diegovskytl commented Jul 14, 2024

I tried to run the example code from Datamancer's documentation:

import datamancer

let s1: seq[int] = @[22, 54, 34]
let s2: seq[float] = @[1.87, 1.75, 1.78]
let s3: seq[string] = @["Mike", "Laura", "Sue"]

let dfAutoNamed = toDf(s1, s2, s3)

echo dfAutoNamed

As a compiled binary works great. Out of curiosity I tried to run it as a Nimscript but I get the following output:

command: nim datamancer_intro.nims

output:

Hint: used config file '/opt/homebrew/Cellar/nim/2.0.8/nim/config/nim.cfg' [Conf]
Hint: used config file '/opt/homebrew/Cellar/nim/2.0.8/nim/config/config.nims' [Conf]
/Users/nox/.nimble/pkgs2/nimblas-0.3.0-d5033749759fc7a2a316acf623635dcb6d69d32a/nimblas/private/common.nim(52, 7) Hint: Using BLAS library with name: libblas.dylib [User]
/Users/nox/.nimble/pkgs2/arraymancer-0.7.32-e1fa31ad09f0199e93c1bf9959e1f3af5bdacc08/arraymancer/tensor/init_cpu.nim(245, 18) template/generic instantiation of `randomTensorCpu` from here
/Users/nox/.nimble/pkgs2/arraymancer-0.7.32-e1fa31ad09f0199e93c1bf9959e1f3af5bdacc08/arraymancer/tensor/init_cpu.nim(218, 18) template/generic instantiation of `allocCpuStorage` from here
/Users/nox/.nimble/pkgs2/arraymancer-0.7.32-e1fa31ad09f0199e93c1bf9959e1f3af5bdacc08/arraymancer/laser/tensor/datatypes.nim(110, 29) template/generic instantiation of `finalizer` from here
/Users/nox/.nimble/pkgs2/arraymancer-0.7.32-e1fa31ad09f0199e93c1bf9959e1f3af5bdacc08/arraymancer/laser/tensor/datatypes.nim(77, 23) Error: attempting to call undeclared routine: 'deallocShared'

Is there a solution or workaround?

It would be nice for Datamancer to work in scripts so when REPL is available for Nim, a tool similar to R/Jupyter Notebooks could be built.

@Vindaar
Copy link
Member

Vindaar commented Jul 16, 2024

So there's two things to mention:

  1. We can make (most of) Datamancer work with NimScript by making it pick the recently added JS backend (see add basic JS support by using custom Tensor replacement #62). It more or less works, I've tried it locally (Note that it still throws some errors when using nim secret due to std/random).
  2. With Nim secret there is a REPL already that uses NimScript. If we ever get a good real REPL, it'll end up compiling the code anyway and Datamancer will work as expected using the "default" backend.

For 1), here is the patch I used. Apply it to a local Datamancer version of yours and your nimscript code should run. Maybe I'll merge it one of these days, but at the moment I don't think it's extremely useful.

diff --git a/src/datamancer/column.nim b/src/datamancer/column.nim
index bf71741..34f9e2f 100644
--- a/src/datamancer/column.nim
+++ b/src/datamancer/column.nim
@@ -1,7 +1,7 @@
-when not defined(js):
-  import arraymancer/tensor
-else:
+when defined(js) or defined(NimScript):
   import seq_tensor
+else:
+  import arraymancer/tensor
 
 import std / [sugar, strformat, tables, macros, strutils]
 import value
diff --git a/src/datamancer/dataframe.nim b/src/datamancer/dataframe.nim
index cdd8025..4a5dc5e 100644
--- a/src/datamancer/dataframe.nim
+++ b/src/datamancer/dataframe.nim
@@ -1,12 +1,12 @@
 import std / [macros, tables, strutils, options, sets, hashes, math,
               sequtils, stats, strformat, algorithm, typetraits]
 
-when not defined(js):
-  import arraymancer/tensor
-  export tensor
-else:
+when defined(js) or defined(NimScript):
   import seq_tensor
   export seq_tensor
+else:
+  import arraymancer/tensor
+  export tensor
 
 import value
 export value
diff --git a/src/datamancer/formulaExp.nim b/src/datamancer/formulaExp.nim
index 8f12ecb..8c1640a 100644
--- a/src/datamancer/formulaExp.nim
+++ b/src/datamancer/formulaExp.nim
@@ -709,7 +709,7 @@ proc convertLoop(p: Preface, dtype, fctColResType, loop: NimNode,
                  fnKind: FormulaKind,
                  generateLoop: bool): NimNode =
   let memCopyable = ["float", "int", "bool"]
-  when defined(js):
+  when defined(js) or defined(NimScript):
     let isMemcopyable = false
   else:
     let isMemCopyable = dtype.strVal in memCopyable and
diff --git a/src/datamancer/io.nim b/src/datamancer/io.nim
index 8bc6eb9..f0f9611 100644
--- a/src/datamancer/io.nim
+++ b/src/datamancer/io.nim
@@ -1,7 +1,7 @@
 import dataframe, value, column
 
 import std / [streams, strutils, tables, parsecsv, sequtils,  strformat, os]
-when not defined(js):
+when not (defined(js) or defined(NimScript)):
   import memfiles
   # for reading CSV files from URLs (former) and `showBrowsers` (latter)
   import httpclient, browsers
@@ -79,8 +79,7 @@ proc readCsv*(s: Stream,
       result[colHeaders[i]].add parser.rowEntry(col)
   parser.close()
 
-
-when defined(js):
+when defined(js) or defined(NimScript):
   type
     MemoryView[T] = seq[T]
 
@@ -109,7 +108,7 @@ template copyBuf(data: MemoryView[char], buf: var string,
   let nIdx = idx - colStart
   if nIdx > 0:
     buf.setLen(nIdx) # will auto reallocate if `len` is larger than capacity!
-    when defined(js):
+    when defined(js) or defined(NimScript):
       for i in 0 ..< nIdx:
         buf[i] = data[colStart + i]
     else:
@@ -667,7 +666,7 @@ proc parseCsvString*(csvData: string,
                             skipInitialSpace, quote, maxGuesses, lineBreak, eat,
                             allowLineBreaks = allowLineBreaks)
 
-when not defined(js):
+when not (defined(js) or defined(NimScript)):
   proc readCsvFromUrl(url: string,
                 sep: char = ',',
                 header: string = "",
@@ -749,7 +748,7 @@ when not defined(js):
     ## parser using `std/parsecsv` is available under the name `readCsvAlt`. However,
     ## it does not return a full `DataFrame`. You need to call `toDf` on the result.
     if fname.startsWith("http://") or fname.startsWith("https://"):
-      when not defined(js):
+      when not (defined(js) or defined(NimScript)):
         return readCsvFromUrl(fname, sep=sep, header=header, skipLines=skipLines,
                               toSkip=toSkip, colNames=colNames)
       else:
@@ -757,7 +756,7 @@ when not defined(js):
     let fname = fname.expandTilde()
     result = newDataFrame()
     try:
-      when not defined(js):
+      when not (defined(js) or defined(NimScript)):
         var ff = memfiles.open(fname)
         var lineCnt = 0
         for slice in memSlices(ff, delim = lineBreak, eat = eat):
@@ -891,7 +890,7 @@ proc toHtml*[C: ColumnLike](df: DataTable[C], tmpl = ""): string =
   body.add "</tbody>"
   result = tmpl % (header & body)
 
-when not defined(js):
+when not (defined(js) or defined(NimScript)):
   proc showBrowser*[C: ColumnLike](
     df: DataTable[C], fname = "df.html", path = getTempDir(), toRemove = false,
     htmlTmpl = "", title = "") =

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

No branches or pull requests

2 participants