Script BASIC

Open Forum => What's New => Topic started by: support on May 30, 2013, 12:00:53 PM

Title: ScriptBasic JIT
Post by: support on May 30, 2013, 12:00:53 PM
Charles Pegge (OxygenBasic / DLLC author) has done it again and added JIT (Just-In-Time) function scripting, compiling and calling all at runtime. The following example is interesting as it shows DLLC supporting the JAPI  (Java Application Programming Interface) and using JIT for the Mandelbrot Set calculation. (76,800 pixel calculations)


(http://files.allbasic.info/ScriptBasic/mandeljit.png)

The following code is using DLLC to interface with the JAPI DLL to produce the Mandelbrot Set.

Code: [Select]
' JAPI 2.0 DLLC

include "dllcinc.sb"

japi = dllfile("japi.dll")

j_start = dllproc(japi, "j_start i = ()")
j_frame = dllproc(japi, "j_frame i = (c * label)")
j_menubar = dllproc(japi, "j_menubar i = ( i obj)")
j_menu = dllproc(japi, "j_menu i = (i obj, c *label)")
j_menuitem = dllproc(japi, "j_menuitem i = (i obj, c *label)")
j_canvas = dllproc(japi, "j_canvas i = (i obj, i width , i height)")
j_setpos = dllproc(japi, "j_setpos (i obj, i xpos, i ypos)")
j_pack = dllproc(japi, "j_pack (i obj)")
j_show = dllproc(japi, "j_show (i obj)")
j_getaction = dllproc(japi, "j_getaction i = ()")
j_nextaction = dllproc(japi, "j_nextaction i = ()")
j_setcolor = dllproc(japi, "j_setcolor (i obj, i r, i g, i b)")
j_drawpixel = dllproc(japi, "j_drawpixel (i obj, i x, i y)")
j_quit = dllproc(japi, "j_quit ()")

CONST J_TRUE = 1
CONST J_FALSE = 0


xstart = -1.8
xend   =  0.8
ystart = -1.0
yend   =  1.0

hoehe  = 240
breite = 320

if (dllcall(j_start) = J_FALSE) then
  print("JAPI interface failed to start.\n")
  end
endif

jframe  = dllcall(j_frame,"JAPI 2.0 DLLC")
menubar = dllcall(j_menubar,jframe)
jfile   = dllcall(j_menu,menubar,"File")
calc    = dllcall(j_menu,menubar,"Calc")
quit    = dllcall(j_menuitem,jfile,"Quit")
start   = dllcall(j_menuitem,calc,"Start")
jstop   = dllcall(j_menuitem,calc,"Stop")

canvas  = dllcall(j_canvas,jframe,breite,hoehe)
dllcall(j_setpos,canvas,10,60)
dllcall(j_pack,jframe)
dllcall(j_show,jframe)

obj = 0
do_work = 0

while((obj <> jframe) and (obj <> quit))

    if(do_work = 1) then
        obj = dllcall(j_getaction)
    else
        obj = dllcall(j_nextaction)
    endif      

    if(obj = start) then
        x = -1
        y = -1
        do_work = 1
        st = dllsecs()
    endif

    if(obj = jstop) then
        do_work = 0
    endif
    
    if(do_work = 1) then
        x = (x+1) % breite
       if(x = 0) then
            y = (y+1) % hoehe
       endif
       if((x = breite-1) and (y = hoehe-1)) then
            do_work = 0
            PRINT format("%g",dllsecs() - st),"\n"
        else
            zre = xstart + x*(xend-xstart)/breite
            zim = ystart + y*(yend-ystart)/hoehe
            it = mandel(zre,zim,512)
            dllcall(j_setcolor,canvas,it*11,it*13,it*17)
            dllcall(j_drawpixel,canvas,x,y)
        endif
    endif

wend

dllcall(j_quit)


function mandel(zre,zim,maxiter)
    mx = 0.0
    my = 0.0
    iter=0
    betrag=0.0
 
    while ((iter < maxiter) and (betrag < 4.0))
        iter = iter+1
        tmp = mx*mx-my*my+zre
        my = 2*mx*my+zim
        mx = tmp
        betrag = (mx*mx + my*my)
    wend
    mandel=iter
end function

This version uses the new JIT compiling feature of DLLC with the mandel() function compiled at runtime.

Code: [Select]
' JAPI 2.0 DLLC JIT

include "dllcinc.sb"

oxy = dllfile("/sb22/modules/oxygen.dll")

o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )
o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )
o2_error = dllproc( oxy, "o2_error c*=()         " )
o2_errno = dllproc( oxy, "o2_errno i =()         " )
o2_len   = dllproc( oxy, "o2_len   i =()         " )
o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " )

dllcall(o2_mode,1)

src = """
extern
function mandel(float zre,zim,sys maxiter) as sys
    float mx,my,betrag
    sys iter
 
    while iter < maxiter and betrag < 4.0
        iter = iter+1
        tmp = mx*mx-my*my+zre
        my = 2*mx*my+zim
        mx = tmp
        betrag = (mx*mx + my*my)
    wend
    return iter
end function

sub finish()
  terminate
end sub

function link(sys n) as sys
  select n
    case 0
      return @finish
    case 1
      return @mandel
  end select
end function

end extern

addr link
"""

dllcall(o2_basic, src)
dfn = dllcall(o2_exec,0)
mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))
finish = dllproc(dfn,"finish ()", dllcald(dfn, 0))

japi = dllfile("japi.dll")

j_start = dllproc(japi, "j_start i = ()")
j_frame = dllproc(japi, "j_frame i = (c * label)")
j_menubar = dllproc(japi, "j_menubar i = ( i obj)")
j_menu = dllproc(japi, "j_menu i = (i obj, c *label)")
j_menuitem = dllproc(japi, "j_menuitem i = (i obj, c *label)")
j_canvas = dllproc(japi, "j_canvas i = (i obj, i width , i height)")
j_setpos = dllproc(japi, "j_setpos (i obj, i xpos, i ypos)")
j_pack = dllproc(japi, "j_pack (i obj)")
j_show = dllproc(japi, "j_show (i obj)")
j_getaction = dllproc(japi, "j_getaction i = ()")
j_nextaction = dllproc(japi, "j_nextaction i = ()")
j_setcolor = dllproc(japi, "j_setcolor (i obj, i r, i g, i b)")
j_drawpixel = dllproc(japi, "j_drawpixel (i obj, i x, i y)")
j_quit = dllproc(japi, "j_quit ()")

CONST J_TRUE = 1
CONST J_FALSE = 0


xstart = -1.8
xend   =  0.8
ystart = -1.0
yend   =  1.0

hoehe  = 240
breite = 320

if (dllcall(j_start) = J_FALSE) then
  print("JAPI interface failed to start.\n")
  end
endif

jframe  = dllcall(j_frame,"JAPI 2.0 DLLC JIT")
menubar = dllcall(j_menubar,jframe)
jfile   = dllcall(j_menu,menubar,"File")
calc    = dllcall(j_menu,menubar,"Calc")
quit    = dllcall(j_menuitem,jfile,"Quit")
start   = dllcall(j_menuitem,calc,"Start")
jstop   = dllcall(j_menuitem,calc,"Stop")

canvas  = dllcall(j_canvas,jframe,breite,hoehe)
dllcall(j_setpos,canvas,10,60)
dllcall(j_pack,jframe)
dllcall(j_show,jframe)

obj = 0
do_work = 0

while((obj <> jframe) and (obj <> quit))
    if(do_work = 1) then
        obj = dllcall(j_getaction)
    else
        obj = dllcall(j_nextaction)
    endif      

    if(obj = start) then
        x = -1
        y = -1
        do_work = 1
        st = dllsecs()
    endif

    if(obj = jstop) then
        do_work = 0
    endif
    
    if(do_work = 1) then
        x = (x+1) % breite
       if(x = 0) then
            y = (y+1) % hoehe
       endif
       if((x = breite-1) and (y = hoehe-1)) then
            do_work = 0
            PRINT format("%g",dllsecs() - st),"\n"
        else
            zre = xstart + x*(xend-xstart)/breite
            zim = ystart + y*(yend-ystart)/hoehe
            it = dllcall(mandel,zre,zim,512)
            dllcall(j_setcolor,canvas,it*11,it*13,it*17)
            dllcall(j_drawpixel,canvas,x,y)
        endif
    endif
wend

dllcall(Finish)
dllcall(j_quit)
dllfile

When the menu start option is clicked I record the time and print the results when the last pixel is displayed of the Mandelbrot Set.

ScriptBasic
C:\SB22\japi_dllc>scriba mandel_dllc.sb
56.9223

C:\SB22\japi_dllc>

ScriptBasic JIT

C:\SB22\japi_dllc>scriba mandel_dllc2.sb
17.608

C:\SB22\japi_dllc>

Title: Re: ScriptBasic JIT
Post by: support on June 01, 2013, 01:39:02 AM
I converted the JAPI Mandelbrot Set to Simple Window to compare the speed of the two libraries.

(http://files.allbasic.info/ScriptBasic/swmadeljit.png)

Code: OxygenBasic
  1. ' Simple Window DLLC JIT
  2.  
  3. include "dllcinc.sb"
  4.  
  5. oxy = dllfile("/sb22/modules/oxygen.dll")
  6.  
  7. o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )
  8. o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )
  9. o2_error = dllproc( oxy, "o2_error c*=()         " )
  10. o2_errno = dllproc( oxy, "o2_errno i =()         " )
  11. o2_len   = dllproc( oxy, "o2_len   i =()         " )
  12. o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " )
  13.  
  14. dllcall(o2_mode,1)
  15.  
  16. src = """
  17. extern
  18. function mandel(float zre,zim,sys maxiter) as sys
  19.     float mx,my,betrag
  20.     sys iter
  21.  
  22.     while iter < maxiter and betrag < 4.0
  23.         iter = iter+1
  24.         tmp = mx*mx-my*my+zre
  25.         my = 2*mx*my+zim
  26.         mx = tmp
  27.         betrag = (mx*mx + my*my)
  28.     wend
  29.     return iter
  30. end function
  31.  
  32. sub finish()
  33.   terminate
  34. end sub
  35.  
  36. function link(sys n) as sys
  37.   select n
  38.     case 0
  39.       return @finish
  40.     case 1
  41.       return @mandel
  42.   end select
  43. end function
  44.  
  45. end extern
  46.  
  47. addr link
  48. """
  49.  
  50. dllcall(o2_basic, src)
  51. dfn = dllcall(o2_exec,0)
  52. mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))
  53. finish = dllproc(dfn,"finish ()", dllcald(dfn, 0))
  54.  
  55. sw = dllfile("sw.dll")
  56.  
  57. Window = dllproc(sw, "Window i = (i width, i height, i mode)")
  58. SetCaption = DLLC_Proc(sw, "SetCaption i = (c *capText)")
  59. SetPixel = dllproc(sw, "SetPixel i = (i xPos, i yPos, i color)")
  60. RGB = dllproc(sw, "RGB i = (i rValue, i gValue, i bValue)")
  61. Redraw = DLLC_Proc(sw, "Redraw ( )")
  62. WaitKey = dllproc(sw, "WaitKey i = ( )")
  63. Quit = DLLC_Proc(sw, "Quit i = ( )")
  64.  
  65.  
  66. xstart = -1.8
  67. xend   =  0.8
  68. ystart = -1.0
  69. yend   =  1.0
  70.  
  71. hoehe  = 240
  72. breite = 320
  73.  
  74. dllcall(Window,320,240,1)
  75. dllcall(SetCaption,"SB SW DLLC JIT")
  76.  
  77. st = dllsecs()
  78.  
  79. x = -1
  80. y = -1
  81.  
  82. REPEAT
  83.   x = (x+1) % breite
  84.   if(x = 0) then y = (y+1) % hoehe
  85.   zre = xstart + x*(xend-xstart)/breite
  86.   zim = ystart + y*(yend-ystart)/hoehe
  87.   it = dllcall(mandel,zre,zim,512)
  88.   dllcall(SetPixel,x, y, dllcall(RGB,it*11,it*13,it*17))
  89.   dllcall(Redraw)
  90. UNTIL ((x = breite-1) and (y = hoehe-1))
  91. PRINT format("%g",dllsecs() - st),"\n"
  92. dllcall(WaitKey)
  93.  
  94. dllcall(Finish)
  95. dllcall(Quit)
  96. dllfile
  97.  

C:\SB22\japi_dllc>scriba swmandeldllc.sb
5.57576

C:\SB22\japi_dllc>

If I remove the Redraw() function and wait until the it's done to refresh the screen.

C:\SB22\japi_dllc>scriba swmandeldllc.sb
1.05691

C:\SB22\japi_dllc>

This is stock SB with no JIT assist.

Code: OxygenBasic
  1. ' Simple Window DLLC
  2.  
  3. include "dllcinc.sb"
  4.  
  5. sw = dllfile("sw.dll")
  6.  
  7. Window = dllproc(sw, "Window i = (i width, i height, i mode)")
  8. SetCaption = DLLC_Proc(sw, "SetCaption i = (c *capText)")
  9. SetPixel = dllproc(sw, "SetPixel i = (i xPos, i yPos, i color)")
  10. RGB = dllproc(sw, "RGB i = (i rValue, i gValue, i bValue)")
  11. Redraw = DLLC_Proc(sw, "Redraw ( )")
  12. WaitKey = dllproc(sw, "WaitKey i = ( )")
  13. Quit = DLLC_Proc(sw, "Quit i = ( )")
  14.  
  15. function mandel(zre,zim,maxiter)
  16.     mx = 0.0
  17.     my = 0.0
  18.     iter=0
  19.     betrag=0.0
  20.  
  21.     while ((iter < maxiter) and (betrag < 4.0))
  22.         iter = iter+1
  23.         tmp = mx*mx-my*my+zre
  24.         my = 2*mx*my+zim
  25.         mx = tmp
  26.         betrag = (mx*mx + my*my)
  27.     wend
  28.     mandel=iter
  29. end function
  30.  
  31. xstart = -1.8
  32. xend   =  0.8
  33. ystart = -1.0
  34. yend   =  1.0
  35.  
  36. hoehe  = 240
  37. breite = 320
  38.  
  39. dllcall(Window,320,240,1)
  40. dllcall(SetCaption,"SB SW DLLC")
  41.  
  42. st = dllsecs()
  43.  
  44. x = -1
  45. y = -1
  46.  
  47. REPEAT
  48.   x = (x+1) % breite
  49.   if(x = 0) then y = (y+1) % hoehe
  50.   zre = xstart + x*(xend-xstart)/breite
  51.   zim = ystart + y*(yend-ystart)/hoehe
  52.   it = mandel(zre,zim,512)
  53.   dllcall(SetPixel,x, y, dllcall(RGB,it*11,it*13,it*17))
  54. UNTIL ((x = breite-1) and (y = hoehe-1))
  55. dllcall(Redraw)
  56. PRINT format("%g",dllsecs() - st),"\n"
  57. dllcall(WaitKey)
  58.  
  59. dllcall(Quit)
  60. dllfile
  61.  

With Redraw() in the loop.

C:\SB22\japi_dllc>scriba swnojit.sb
45.0972

C:\SB22\japi_dllc>

Wait until the end to display the results.

C:\SB22\japi_dllc>scriba swnojit.sb
39.637

C:\SB22\japi_dllc>
Title: Re: ScriptBasic JIT
Post by: kryton9 on July 01, 2013, 01:40:49 PM
John this is impressive looking. Is the aim to get programs compiled for android via java, or I guess for any java supported platform?
Title: Re: ScriptBasic JIT
Post by: support on July 08, 2013, 04:41:24 AM
Quote
Is the aim to get programs compiled for android via java, or I guess for any java supported platform?

The JAPI interface is a great idea but 10 years before it's time. It was abandoned before Java got into full swing. (pun intended) There were a couple other BASIC like developers that showed interest in updating the library from AWT based to SWING based. That effort fizzled out and I have no room on my plate to take on another project. (alone) The other negative aspect is that the Java interface is a socket connection (like GTK-Server) and quickly reaches it limitations with todays processor speed. For this API to be worth using, a more direct interface to Java (JNI) needs to be in place and the full swing API exposed.

My efforts with this as with everything else I do was to try and create some interest in JAPI and see if others felt there was value in a rebirth of the API. Seems not at this time.  :-\

Thanks for the comments and feedback. It gets boring being the only one posting to this open source project.

As a side note, I plan on focusing ScriptBasic toward it's roots of being an embedded scripting solution. I must have been nuts trying to promote ScriptBasic's use to the BASIC hobby programming community. ALLBASIC.INFO will become a what's up with BASIC info/news site without interaction. I no longer have the free time I once had to promote and facilitate BASIC open source projects.

Title: Re: ScriptBasic JIT
Post by: kryton9 on July 10, 2013, 07:46:17 PM
You have done a great job from all your posts I see on various platforms promoting BASIC and ScriptBasic. I am amazed on how much you could keep straight to deal with so many areas and to offer so many nice websites.

I just wish we had the BASIC developers working together instead of all on their own. But I guess everyone has their own ideas on what is best and go forward with their dream.
Title: Re: ScriptBasic JIT
Post by: support on July 10, 2013, 09:55:08 PM
I hope to have better luck with ScriptBasic supporting the embedded world. SB has been embedded in commercial controllers and routers for many years and with little or no help from the author or myself.

There are just too many general purpose BASIC languages out there for SB to make any headway among them. The people I know that have tried ScriptBasic, love it so life can't be all that bad.  :)
Title: Re: ScriptBasic JIT
Post by: RONB on July 18, 2013, 12:58:37 PM
Sounds like a project I would like to try.

embedded Linux microcontroller
scriba
sbhttpd

I was looking at one the other day that would run linux and had lan and wireless built in. Programmed by usb connection.

http://beagleboard.org/


 
Title: Re: ScriptBasic JIT
Post by: support on July 18, 2013, 01:23:32 PM
It seems that energy management and facility monitoring is well on it's way as standard equipment in current construction. Reminds me of the push to put all those wires hanging from poles underground. SB is an excellent embeddable scripting language and used commercially in controllers/gateways.
Title: Re: ScriptBasic JIT
Post by: kryton9 on July 24, 2013, 06:37:21 PM
I am looking at either the raspberry pi or the beaglebone black. I would like to have a dedicated cheap linux machine to experiment with. I guess these are cheap enough can't go wrong picking either one.
http://www.youtube.com/watch?v=Tbk_Z_8macI
Title: Re: ScriptBasic JIT
Post by: support on July 25, 2013, 02:06:01 PM
I was able to compile ScriptBasic in my chrooted copy of Ubuntu ARM on Android.

Let me know if you have any interest of trying ScriptBasic on one of these boards.