[Pharo-users] Few questions about Spec (instance specific layout and skinning)
Hi ! First, I apologyse for the wall of text. I'm trying my hands at Spec and I have few questions: - How can I implement an instance-dependent layout ? Regarding the layout method lookup, the documentation states that it "starts on instance side, which allows a UI to have a more specific layout depending on the state of the instance" I tried to simply put a layout in an instance method with the ** pragma. But not only was it not retrieved by *ComposableModel>#defaultSpecSelector* but *ComposableModel>#retrieveSpec:*will send the selector on the class anyway. What I ended up doing was overiding #openWithSpec (which worked) but I'm pretty sure that my model is not composable at all. - Is it possible to change the "skin" of the basic widget ? I would like to implement some sort of toggle button by changing the color of ButtonModel and so far, I failed. I was not able to trace my color change up to the PluggableButtonMorph because it seems to use anoucement and I'm a Smalltalk rookie. I tried however to send #color: directly to the morph which does nothing: the #changed method rolls it back to its previous value. So I may be doing something wrong but it doesn't feel like the issue comes from Spec. Any clue ? - On a side note, I tried to send an argument to the selector that retrieve a widget in the layout method. And I came up with this : layout *add:* {#buttonAt: . 1}; *add:* {#buttonAt: . 2}; *add:* {#buttonAt: . 3} Is it how it's done ? Thanks in advance ! Thomas.
Re: [Pharo-users] Few questions about Spec (instance specific layout and skinning)
> > The usual solution is to have a method looking like this on instance side > > rebuildMyLayout > > | layout | > layout := self buildStateDependentLayout. > self buildWithLayout: layout. > > buildStateDependentLayout > ^ SpecLayout composed > etc... > I will defenitly look into that. The "rebuild" may be missleading, is it also called at first building ? The hooks are basically here, but the Morphs have an issue with this. > The "skin" of a Morph is supposed to be immutable, hence it takes back its > default value at each refresh :S > Well, I can't even manage to tweak it through hardcoding stuff on the adapter :p Do you think it would be hard to use a SimpleSwitchMorph ? As I understood, there is #asSpecAdapter that permis to plug pretty much everything ? Plus, making a specific adapter seems doable (I mean for a rookie like me). > That's a solution. > Then if you have a fixed number of buttons, you could also implement a > getter for each. > > If you have an undetermined number of button, then DynamicComposableModel > is for you. > Well, I definitely have a variable number of buttons, depending on the model instance. Actualy, I want my model to be a matrix of toggle to specify a mask. I create instance with: MaskModel class>#maxIndex: anInteger ^(self basicNew) maxIndex: anInteger; initialize; yourself and instantiate a collection of buttons in #initializeWidgets. It doesn't change much after that so a DynamicComposableModel didn't seem usefull. But I only though that because I never used it. I will give it a try. Anyway, thanks again for your time ! Thomas.
Re: [Pharo-users] Few questions about Spec (instance specific layout and skinning)
Hey, I have a quick question. I'm trying to build an adapter (called MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout on the ones in existing adapter (namely MorphicButtonAdapter). And I get stuck in an infinite loop during the interpretation of the layout of the adapter. The first lines are: ^ {#SimpleSwitchMorph. #onColor:. #(model onColor). #offColor:. #(model #offColor) etc... At some point, it tries to interpret #(#model #offColor)) and a few step latter, it comes back to step one and tries to interpret #(#MorphicSwitchAdapter #adapt: #model). I tried this alternative {#model. #onColor} (though this one is equivalent to me) and this one #model. #onColor. but to no avail. I have a feeling that the problem stems from the fact that PluggableButtonMorph seems to allready be an adapter which take a model while SimpleSwitchMorp does not. Could you throw some light as to why the interpretation fails ? Again, thanks for your help ! Thomas.
Re: [Pharo-users] Few questions about Spec (instance specific layout and skinning)
Hum, I was pondering the problem at home and started from scratch. I don't have the issue anymore ... 2014-04-03 18:40 GMT+02:00 Thomas Bany : > Hey, > > I have a quick question. I'm trying to build an adapter (called > MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout > on the ones in existing adapter (namely MorphicButtonAdapter). > > And I get stuck in an infinite loop during the interpretation of the > layout of the adapter. > > The first lines are: > > ^ {#SimpleSwitchMorph. > #onColor:. #(model onColor). > #offColor:. #(model #offColor) > etc... > > At some point, it tries to interpret #(#model #offColor)) and a few step > latter, it comes back to step one and tries to interpret > #(#MorphicSwitchAdapter > #adapt: #model). > > I tried this alternative {#model. #onColor} (though this one is > equivalent to me) and this one #model. #onColor. but to no avail. > > I have a feeling that the problem stems from the fact that > PluggableButtonMorph seems to allready be an adapter which take a model > while SimpleSwitchMorp does not. > > Could you throw some light as to why the interpretation fails ? > > Again, thanks for your help ! > > Thomas. >
Re: [Pharo-users] Few questions about Spec (instance specific layout and skinning)
Okey so I looked deeper into the interpreter and found that the receiver of the next call is the returned value of the previous. I'm pretty sure it explains the infinite loop I was encountering. It also made it problematic to register the morph to the anouncement of the adapter, since #addDependent: is send with a morph to the model and I needed the other way arround. Adding #beDependentTo: somewhere in the class hierarchy of SimpleSwitchMorph make it work but I'm not sure I should do that. 2014-04-03 20:37 GMT+02:00 Thomas Bany : > Hum, I was pondering the problem at home and started from scratch. I don't > have the issue anymore ... > > > 2014-04-03 18:40 GMT+02:00 Thomas Bany : > > Hey, >> >> I have a quick question. I'm trying to build an adapter (called >> MorphicSwitchAdapter) and a model for SimpleSwitchMorp. I based my layout >> on the ones in existing adapter (namely MorphicButtonAdapter). >> >> And I get stuck in an infinite loop during the interpretation of the >> layout of the adapter. >> >> The first lines are: >> >> ^ {#SimpleSwitchMorph. >> #onColor:. #(model onColor). >> #offColor:. #(model #offColor) >> etc... >> >> At some point, it tries to interpret #(#model #offColor)) and a few step >> latter, it comes back to step one and tries to interpret >> #(#MorphicSwitchAdapter >> #adapt: #model). >> >> I tried this alternative {#model. #onColor} (though this one is >> equivalent to me) and this one #model. #onColor. but to no avail. >> >> I have a feeling that the problem stems from the fact that >> PluggableButtonMorph seems to allready be an adapter which take a model >> while SimpleSwitchMorp does not. >> >> Could you throw some light as to why the interpretation fails ? >> >> Again, thanks for your help ! >> >> Thomas. >> > >
[Pharo-users] Use of FileDialogWindow : getting the result
Hi ! I'm trying to fit a GUI in full screen mode, that uses a FileDialogWindow at some point. I'm able to recover the answer from FileDialogWindow when I it is opened modaly. However, since I would like to open it fullscreen with the selector #openFullScreen, the calling block does not wait and immediatly gets a nil answer. I was thinking of hacking my way out of it and subclassing FileDialogWindow to overide a method somewhere to call a block of my choosing but I really does not feel right. Has anyone a clue ? Thanks in advance for your time ! Thomas.
Re: [Pharo-users] Use of FileDialogWindow : getting the result
Okey so I only needed to select a directory and needed to shrink the size of the widget anyway. So I opted for the sublass solution, got rid of the file pane and added an action block on the #ok method. 2014-04-07 16:12 GMT+02:00 Thomas Bany : > Hi ! > > I'm trying to fit a GUI in full screen mode, that uses a FileDialogWindow > at some point. > > I'm able to recover the answer from FileDialogWindow when I it is opened > modaly. However, since I would like to open it fullscreen with the selector > #openFullScreen, the calling block does not wait and immediatly gets a nil > answer. > > I was thinking of hacking my way out of it and subclassing > FileDialogWindow to overide a method somewhere to call a block of my > choosing but I really does not feel right. > > Has anyone a clue ? > > Thanks in advance for your time ! > > Thomas. >
Re: [Pharo-users] Use of FileDialogWindow : getting the result
> > Why do you need a dialog window in fullscreen size, if it is modal anyway > ? > Actualy, I need it to be fullscreen. I mentioned a dialog window because I was only able to retrieve the answer this way but I don't want a dialog window :) > Have you tried FileList (it isn't fullscreen, and doesn't look as nice as > the FileDialogWindow, but maybe it is easier to hack around with.) > > FileList modalFolderSelector: FileSystem disk workingDirectory > Well I think it looks better than my shrank version, I will look into it !
Re: [Pharo-users] open file in append mode
Hi ! I use #setToEnd. Cheers 2014-04-09 10:08 GMT+02:00 Norbert Hartl : > How can I open a file in append mode in order to start writing at the end > of the file? > > thanks, > > Norbert >
[Pharo-users] Memory profiling: usage per class - instance in old memory
Hi, My app is a parser/filter for binary files, that produces a bunch of ascii files. At the begining of the parsing, the filtering step involves the storage of the positions of 32 objects, each second for a whole day. So that's 32 Arrays with 86400 elements each. During this step, the memory used by my image grows from 50Mb to ~500Mb. I find it far too large since I'm pretty sure my arrays are the largest objects I create and only weight something like 300kb. The profiling of the app shows that hte footprint of the "old memory" went up by 350Mb. Which I'm pretty sure is super bad. Maybe as a consequence, after the parsing is finished, the memory footprint of the image stays at ~500Mb What are the tools I have to find where precisely the memory usage explodes ? For example, is it possible to browse the "old memory" objects to see which one fails to get GC'ed ? Thanks in advance, Thomas.
Re: [Pharo-users] Memory profiling: usage per class - instance in old memory
I meant a single array weight something like 300Kb with the 32 of them weighting arround 10Mb. I tried to look closely at the way the memory (with VirtualMachine>#memoryEnd) was incrementing and it follows this pattern: - The memory costly function is defenitly the one storing my position arrays: #setPositionECEFOn: - Throughout the computation of the 32 daily positions, the memory used by the VM goes from 52Mb to 363Mb. Is this a normal behaviour ? On a side note, the computation of a single epoch (which is done 32*24*3600 times) uses 19 local variables. Not sure it is relevant. 2014-04-09 13:10 GMT+02:00 Stephan Eggermont : > Your calculation seem to be off. > 32 * 86400 objects = 2.8 million objects. A shortint = 4 bytes, making > 10.6 MB > Everything else (except value objects) is larger. > > Stephan >
Re: [Pharo-users] Memory profiling: usage per class - instance in old memory
Thanks ! That's exactly what I was looking for. There is a compare method I dont quite understand but I think I found what is going on. I failed to grasp that an Array reply to #sizeInMemory with it's own size, without the sizes of its references. A single position object weight 96 bytes, which make the whole Array weight arround 8Mb, and the 32 objects arround 250 Mb. I'm not sure I can get arround that aspect since the computation is costly and I need its output multiple times. I will make further testing to see why the memory is not released at the end of the execution. Thanks again ! 2014-04-09 15:19 GMT+02:00 Sven Van Caekenberghe : > Hi Thomas, > > Fixing memory consumption problems is hard, but important: memory > efficient code is automatically faster in the long run as well. > > Your issue sounds serious. However, I would start by trying to figure out > what is happening at your coding level: somehow you (or something you use) > must be holding on too much memory. Questioning low level memory management > functionality should be the last resort, not the first. > > There is SpaceTally that you could use before and after running part of > your code. Once something unexpected survives GC, there is the > PointerFinder functionality (Inspector > Explore Pointers) to find what > holds onto objects. But no matter what, it is hard. > > If you have some public code that you could share to demonstrate your > problem, then we could try to help. > > Sven > > On 09 Apr 2014, at 12:54, Thomas Bany wrote: > > > Hi, > > > > My app is a parser/filter for binary files, that produces a bunch of > ascii files. > > > > At the begining of the parsing, the filtering step involves the storage > of the positions of 32 objects, each second for a whole day. So that's 32 > Arrays with 86400 elements each. > > > > During this step, the memory used by my image grows from 50Mb to ~500Mb. > I find it far too large since I'm pretty sure my arrays are the largest > objects I create and only weight something like 300kb. > > > > The profiling of the app shows that hte footprint of the "old memory" > went up by 350Mb. Which I'm pretty sure is super bad. Maybe as a > consequence, after the parsing is finished, the memory footprint of the > image stays at ~500Mb > > > > What are the tools I have to find where precisely the memory usage > explodes ? For example, is it possible to browse the "old memory" objects > to see which one fails to get GC'ed ? > > > > Thanks in advance, > > > > Thomas. > > >
[Pharo-users] Quit without asking to save
Hi ! I'm developping a desktop application for Windows and I want to prevent the user from saving the image. First off, setting the #canSaveImage permission to false does not seems to prevent saving. But it's okey since the user won't have access to the World Menu. However, upon quitting the VM, a dialog pop up asking if I want to quit the image without saving. Is it possible to remove it ? Thanks in advance, Thomas.
Re: [Pharo-users] Quit without asking to save
Thanks !! 2014-04-10 11:43 GMT+02:00 Esteban Lorenzano : > from the app, you quit (without saving) by executing: > > Smalltalk snapshot: false andQuit: true. > > in windows, to disable the annoying dialog "exit without save" when > pressing the close button, you need to add: > > EnableAltF4Quit=0 > > to the ini file (honestly, that should be the default, but is not).That > will actually send a message to the image that will end in: > > WorldState>>#quitSession > > which is a method that handles world close. > > You need to override that method to get the usage you want :) > > cheers, > Esteban > > On 10 Apr 2014, at 11:09, Thomas Bany wrote: > > > Hi ! > > > > I'm developping a desktop application for Windows and I want to prevent > the user from saving the image. > > > > First off, setting the #canSaveImage permission to false does not seems > to prevent saving. But it's okey since the user won't have access to the > World Menu. > > > > However, upon quitting the VM, a dialog pop up asking if I want to quit > the image without saving. Is it possible to remove it ? > > > > Thanks in advance, > > > > Thomas. > > >
Re: [Pharo-users] Memory profiling: usage per class - instance in old memory
Okey so I have found the Class instance that was holding onto the data. I can now save my image after a parsing without tripling its size. But the VM's memory footprint (according to Windows task manager) does not falls back to normal after a parse. My guess is that now that the VM was allocated more space, it juste doesn't give it back. It still bugs me a little since I can see the memory occupied by the VM drop when minimised in the task bar. > If you want to use a huge data structure, you have to think carefully > about your representations. There are tricks you can use to conserve > memory: use more primitive types (SmallIntegers, bit flags, Symbols), use > shared instances, use alternatives like ZTimestamp which is half the size > of DateAndTime, or use your own integer time, sparse data structures, and > so on - and you can hide these optimisations behind your standard API. > I have a quick question regarding primitive type: 1 sizeInMemory -> 0 1.0 sizeInMemory -> 12 I do use a integer as my timestamp, encapsulated in a class, which also weight 12 bytes. This makes me think that the a Float weighting 12 bytes is an encapsulation of a primitive type I don't know of. If so, is it possible to not use a Float, but something like a double ? Thomas.
[Pharo-users] NativeBoost: structure with different types
Hi everyone ! I experience troubles with NBExternalStructure in NativeBoost when the structure modeled contains fields with different types. For example, manipulating the following structure poses no problem and I can manipulate the fields correctly: typedef struct abc_s { double a; double b; double c; } abc; However, setting field 'a' to be an int yields the following symptoms: ¤ From Pharo to C (function with 'abc' as argument type), the fields are badly read. ¤ From C to Pharo (function with 'abc' as return type), the VM crash without an error nor a dump. Am I doing something wrong or is it maybe specific to the compiler I use (the one that comes with Visual Studio Express 2013) ? I'm pretty sure I could go arround this using NBExternalObject and building the structure on C side, but it would be nice to avoid it. On a side note, my understanding is that creating a structure on Pharo side will have it stored in Pharo memory. Is it problematic when it comes to pass it by value ? Or should I manage the copying on the C heap to be safe ? Thomas.
Re: [Pharo-users] NativeBoost: structure with different types
The compiler indeed inserted 32 dummy bits between the first (32 bits) and second (64 bits) field. It feels like it want to align its 64 bits fields on 64 bits chunk of bits because the 32 bits fields at the end of my structure are contiguous. Simply move the first 32 bits field at the end of the structure might sovle it ! Thanks a lot for the quick response !! 2014-08-04 13:18 GMT+02:00 Igor Stasenko : > > > > On 4 August 2014 12:37, Thomas Bany wrote: > >> Hi everyone ! >> >> I experience troubles with NBExternalStructure in NativeBoost when the >> structure modeled contains fields with different types. For example, >> manipulating the following structure poses no problem and I can manipulate >> the fields correctly: >> >> typedef struct abc_s { >> double a; >> double b; >> double c; >> } abc; >> >> However, setting field 'a' to be an int yields the following symptoms: >> ¤ From Pharo to C (function with 'abc' as argument type), the fields >> are badly read. >> ¤ From C to Pharo (function with 'abc' as return type), the VM crash >> without an error nor a dump. >> >> Am I doing something wrong or is it maybe specific to the compiler I use >> (the one that comes with Visual Studio Express 2013) ? >> >> >> > This caused by wrong alignment of structure in memory. Different compilers > can align structures differently, and there's no way to know it at run time. > > Try to change the # > *byteAlignment of the structure.Also, if nothing helps, you can use dummy > fields* for padding fields, like in your example: > > int a; > int dummy; > double b; > double c; > > >> I'm pretty sure I could go arround this using NBExternalObject and >> building the structure on C side, but it would be nice to avoid it. >> >> >> On a side note, my understanding is that creating a structure on Pharo >> side will have it stored in Pharo memory. Is it problematic when it comes >> to pass it by value ? Or should I manage the copying on the C heap to be >> safe ? >> >> >> Thomas. >> >> > > > -- > Best regards, > Igor Stasenko. >
[Pharo-users] NativeBoost: use of array
Hi again ! I'm having trouble to call the function with the following prototype : void propagateTLE(orbit_t orb, double secondSince[], xyz_t * out, size_t > nbEpoch) with the corresponding NB call: self nbCall: #( void propagateTLE(orbit_t orbit, double * secondSince, > xyz_t * out, size_t nbEpoch) ) The argument *secondSince* is an input and the argument *out* is the output pointer that the function should fill. I have made 2 subclass of NBExternalArray to feed this function, (allmost) namely: *ArrayOfDoubles *and *ArrayOfXYZ*. Should I mention that type *xyz_t* is a struct that I modeled with an *NBExternalStructure*. I face 2 issues: - The type *ArrayOfXYZ* is refused as an *xyz_t** type. However, the *ArrayOfDoubles *is accepted as a *double** type. - If a get rid of the *out* argument to test the array *secondSince*, I get an undefined error (Error durring FFI call: nil). My current solution is to use the adress of my arrays and the following NB call: self nbCall: #( void propagateTLE(orbit_t orbit, NBExternalAddress > secondSince, NBExternalAddress out, size_t nbEpoch) ) But it feels like I'm cheating my way trough, by pretty much avoiding any type check. Any clue as to why the typecheck of NB is refusing to call my function ? Thanks in advance, Thomas.
Re: [Pharo-users] NativeBoost: use of array
All right ! Tanks again for you answers and kudos for the NB plugin ! I was kinda scared of doing stuff outside of the image but everything went super smooth. 2014-08-05 16:45 GMT+02:00 Igor Stasenko : > > > > On 4 August 2014 16:45, Thomas Bany wrote: > >> Hi again ! >> >> >> I'm having trouble to call the function with the following prototype : >> >> void propagateTLE(orbit_t orb, double secondSince[], xyz_t * out, size_t >>> nbEpoch) >> >> >> with the corresponding NB call: >> >> self nbCall: #( void propagateTLE(orbit_t orbit, double * secondSince, >>> xyz_t * out, size_t nbEpoch) ) >> >> >> The argument *secondSince* is an input and the argument *out* is the >> output pointer that the function should fill. I have made 2 subclass of >> NBExternalArray to feed this function, (allmost) namely: *ArrayOfDoubles >> *and *ArrayOfXYZ*. Should I mention that type *xyz_t* is a struct that I >> modeled with an *NBExternalStructure*. >> >> I face 2 issues: >> >>- The type *ArrayOfXYZ* is refused as an *xyz_t** type. However, the >> *ArrayOfDoubles >>*is accepted as a *double** type. >>- If a get rid of the *out* argument to test the array *secondSince*, >>I get an undefined error (Error durring FFI call: nil). >> >> >> >> My current solution is to use the adress of my arrays and the following >> NB call: >> >> self nbCall: #( void propagateTLE(orbit_t orbit, NBExternalAddress >>> secondSince, NBExternalAddress out, size_t nbEpoch) ) >> >> >> if you explicitly specify NBExternalAddress, then it won't accept any > other argument than instance of NBExternalAddress. > > Also, note there's no marshallers for (sub)instances of NBExternalArray, > and thus you cannot pass them directly, but only by passing pointer to its > elements using #address method. > > I.e, if you using 'whatever *', you can pass a pointer to array by: > myArray address. > > > >> But it feels like I'm cheating my way trough, by pretty much avoiding any >> type check. Any clue as to why the typecheck of NB is refusing to call my >> function ? >> >> >> Thanks in advance, >> >> Thomas. >> >> > > > -- > Best regards, > Igor Stasenko. >
Re: [Pharo-users] Question on Spec
Hi ! Did you call 'super initailizeWidgets' in the 'initializeWidgets' method of all the subclass of AbstractPanel ? Thomas. 2014-08-06 11:16 GMT+02:00 Mark Rizun : > Actually in each:) > I have a class AbstractPanel and there is: > > initializeWidgets > self instantiateModels: #(#templateText #MyTextModel). > templateText > dragEnabled; > text: self demoText; > ast: (RBParser parseRewriteExpression: self demoText); > aboutToStyle: true; > model: self; > menuOptionsSelector: #menuActions > > MyTextModel is a subclass of TextModel > > > > 2014-08-06 11:13 GMT+02:00 Benjamin > : > > On 06 Aug 2014, at 11:04, Mark Rizun wrote: >> >> initializeWidgets >> self >> instantiateModels: #(#sourcePanel #SourcePanel #resultPanel #ResultPanel >> #matchPanel #MatchPanel #transformPanel #TransformPanel #acceptButton >> #ButtonModel). >> >> >> Sounds correct so far :) >> >> In wich panel is your TextModel? >> Can you show me your `initializeWidgets` method for this panel? >> >> >> Ben >> > >
Re: [Pharo-users] Question on Spec
Okey, I hadn't read your question carefully :) Looking at TextModel>>sourceTextArea, it returns the widget of the model, meaning the adapter to PluggableTextMorph. The adapter (and the Morph behind) is instantiated during the building (called in openWithSpec) of the model, not its initialization. In short, when you call RewriteTool new, you have a fully initialized description of the GUI, but you don't have the GUI. Thomas. 2014-08-06 11:45 GMT+02:00 Benjamin : > On 06 Aug 2014, at 11:30, Mark Rizun wrote: > > > Yes it is invoked(I mean initializeWidgets in AbstractPanel) if I do: > RewriteTool new. > > If you put the halt after > `self instantiateModels: #(#templateText #MyTextModel).` > can you confirm that templateText is not nil? > > > And yes, I needed more functionality for TextModel > > Which ones? :) > Maybe they deserve to be pushed into TextModel > > Ben >
Re: [Pharo-users] Question on Spec
Going through the execution of 'openWithSpec', it looks like the method you are looking for is 'buildWithSpec'. It definitely instantiate the adapters as well as the morphs, with the root of the morph tree being nil. I can't tell you if everything will work as intended though, but I don't see why not. Benjamin developed Spec and might be able to answer that. Finaly, I don't quite see what is wrong with opening a window in a test, as long as you send 'close' to your model at the end ? Thomas. 2014-08-06 14:01 GMT+02:00 Benjamin : > Maybe you can manually set the Adapter? > > Ben > > On 06 Aug 2014, at 12:39, Mark Rizun wrote: > > Maybe it can, but it's more convenient for me to subclass it > So, how do I initialize it for tests without opening it with spec? > 6 серп. 2014 12:00, користувач "Benjamin" < > benjamin.vanryseghem.ph...@gmail.com> написав: > >> On 06 Aug 2014, at 11:50, Mark Rizun wrote: >> >> > No they don't:) I just replaced a menu of TextModel with my own, and >> added some ast support. >> >> Can’t the menu be changed dynamically in TextModel? >> >> Ben >> > >
[Pharo-users] NativeBoost : optimisation of the machine code generation
Hi everyone, I'm trying to reduce the computation time of the following pseudo-code: - memory allocation (~40 doubles) - object heap to C heap copying - NativeBoost call (nbCall:) - memory freeing The time profiling results are bellow: - 24*3600 calls : > 1 minute - 24*3600 calls with only memory allocation and copying : < 1 second - 1 call with a 24*3600 loop inside de C code : < 1 second So it appears that the very coslty step is the transition from Pharo to C. And I was wondering if it was possible to drasticly reduce this time by doing something like, generate the the machine code once and call it multiple time ? Thanks in advance ! Thomas.
Re: [Pharo-users] NativeBoost : optimisation of the machine code generation
@ Alexandre: sure, no problem ! @ Luc: I'm not sure how much code I can provide without being to specific, but here is how it goes : - *Let's say I have the Smalltalk code bellow:* *MyClass*>>withNBCall externalArray := *NBExternalArrayOfDoubles *new: *self *internalArray size. output := *NBExternalArrayOfDoubles *new: 4. [*self *actualNBCallWith: externalArray adress storeResultIn: output adress] ensure: [externalArray free. output free]. *MyClass*>>withNBCallCommented externalArray := *NBExternalArrayOfDoubles *new: *self *internalArray size. output := *NBExternalArrayOfDoubles *new: 4. ["self actualNBCallWith: externalArray adress storeResultIn: output adress"] ensure: [externalArray free. output free]. *MyClass*>>actualNBCallWith: externalArray storeResultIn: output ^*self *nbCall: #(void callToC(double * externalArray, double * output)) module: 'lib/myModule.dll' - *And the C code bellow:* *void *callToC(*double ** externalArray, *double ** output) { computationWith(externalArray, output); } *void *specialCallToC(*double ** externalArray, *double ** output) { * unsigned int* i; *for *(i = 0; i < 24*3600; i++) computationWith(externalArray, output); } - *Now I have the following code typed in Time Profiler tool :* object := (*MyClass *new) variousInitialization; yourself 24*3600 timesRepeat: [object withNBCall] >> Over 1 minute computation time of which over 99% are primitives. Also I don't see the nbCall: in the tree. object := (*MyClass *new) variousInitialization; yourself 24*3600 timesRepeat: [object withNBCallCommented] >> Less than 1 second. object := (*MyClass *new) variousInitialization; yourself object withNBCall >> Less than 1 millisecond. object := (*MyClass *new) variousInitialization; yourself object withNBSpecialCall "This time, I use the specialCallToC() function" >> Arround 20 millisecond. Allright, that's a pile of code but I hope it help :) On a side note: - Pharo 3, Win 7 32-bit - I'm not at work anymore and don't have my code with me. So I will double check tomorow that I didn't provided false informations but I think it's accurate of what I do. Again, thanks for the interest on my issue ! Thomas. 2014-08-07 18:39 GMT+02:00 kilon alios : > I think that if you posted the code , preferably that contains only the > problem would be easier to test , debug and investigate. > > > > On Thu, Aug 7, 2014 at 6:25 PM, Thomas Bany wrote: > >> Hi everyone, >> >> I'm trying to reduce the computation time of the following pseudo-code: >> >> - memory allocation (~40 doubles) >> - object heap to C heap copying >> - NativeBoost call (nbCall:) >> - memory freeing >> >> The time profiling results are bellow: >> >> - 24*3600 calls : > 1 minute >> - 24*3600 calls with only memory allocation and copying : < 1 second >> - 1 call with a 24*3600 loop inside de C code : < 1 second >> >> So it appears that the very coslty step is the transition from Pharo to >> C. And I was wondering if it was possible to drasticly reduce this time by >> doing something like, generate the the machine code once and call it >> multiple time ? >> >> Thanks in advance ! >> >> Thomas. >> > >
Re: [Pharo-users] NativeBoost : optimisation of the machine code generation
I forgot the copying of the data from the object heap to C heap: *MyClass*>>withNBCall externalArray := *NBExternalArrayOfDoubles *new: *self *internalArray size. output := *NBExternalArrayOfDoubles *new: 4. 1 to: *self *internalArray size. do: [ :index | externalArray at: index (put: *self *internalArray at: index) ]. [*self *actualNBCallWith: externalArray adress storeResultIn: output adress] ensure: [externalArray free. output free]. *MyClass*>>withNBCallCommented externalArray := *NBExternalArrayOfDoubles *new: *self *internalArray size. output := *NBExternalArrayOfDoubles *new: 4. 1 to: *self *internalArray size. do: [ :index | externalArray at: index (put: *self *internalArray at: index) ]. ["self actualNBCallWith: externalArray adress storeResultIn: output adress"] ensure: [externalArray free. output free]. Thomas. 2014-08-07 19:15 GMT+02:00 Thomas Bany : > @ Alexandre: sure, no problem ! > > @ Luc: > > I'm not sure how much code I can provide without being to specific, but > here is how it goes : > > >- *Let's say I have the Smalltalk code bellow:* > > *MyClass*>>withNBCall >externalArray := *NBExternalArrayOfDoubles *new: *self *internalArray > size. >output := *NBExternalArrayOfDoubles *new: 4. >[*self *actualNBCallWith: externalArray adress storeResultIn: output > adress] > ensure: [externalArray free. output free]. > > *MyClass*>>withNBCallCommented >externalArray := *NBExternalArrayOfDoubles *new: *self *internalArray > size. >output := *NBExternalArrayOfDoubles *new: 4. >["self actualNBCallWith: externalArray adress storeResultIn: output > adress"] ensure: [externalArray free. output free]. > > *MyClass*>>actualNBCallWith: externalArray storeResultIn: output > errorCode> >^*self *nbCall: #(void callToC(double * externalArray, double * > output)) module: 'lib/myModule.dll' > > >- *And the C code bellow:* > > *void *callToC(*double ** externalArray, *double ** output) { >computationWith(externalArray, output); > } > > *void *specialCallToC(*double ** externalArray, *double ** output) { > * unsigned int* i; >*for *(i = 0; i < 24*3600; i++) > computationWith(externalArray, output); > } > > >- *Now I have the following code typed in Time Profiler tool :* > > object := (*MyClass *new) variousInitialization; yourself > 24*3600 timesRepeat: [object withNBCall] > >> Over 1 minute computation time of which over 99% are primitives. Also I > don't see the nbCall: in the tree. > > object := (*MyClass *new) variousInitialization; yourself > 24*3600 timesRepeat: [object withNBCallCommented] > >> Less than 1 second. > > object := (*MyClass *new) variousInitialization; yourself > object withNBCall > >> Less than 1 millisecond. > > object := (*MyClass *new) variousInitialization; yourself > object withNBSpecialCall "This time, I use the specialCallToC() function" > >> Arround 20 millisecond. > > > Allright, that's a pile of code but I hope it help :) > > On a side note: > >- Pharo 3, Win 7 32-bit >- I'm not at work anymore and don't have my code with me. So I will >double check tomorow that I didn't provided false informations but I think >it's accurate of what I do. > > > Again, thanks for the interest on my issue ! > > Thomas. > > > > 2014-08-07 18:39 GMT+02:00 kilon alios : > > I think that if you posted the code , preferably that contains only the >> problem would be easier to test , debug and investigate. >> >> >> >> On Thu, Aug 7, 2014 at 6:25 PM, Thomas Bany wrote: >> >>> Hi everyone, >>> >>> I'm trying to reduce the computation time of the following pseudo-code: >>> >>> - memory allocation (~40 doubles) >>> - object heap to C heap copying >>> - NativeBoost call (nbCall:) >>> - memory freeing >>> >>> The time profiling results are bellow: >>> >>> - 24*3600 calls : > 1 minute >>> - 24*3600 calls with only memory allocation and copying : < 1 second >>> - 1 call with a 24*3600 loop inside de C code : < 1 second >>> >>> So it appears that the very coslty step is the transition from Pharo to >>> C. And I was wondering if it was possible to drasticly reduce this time by >>> doing something like, generate the the machine code once and call it >>> multiple time ? >>> >>> Thanks in advance ! >>> >>> Thomas. >>> >> >> >
Re: [Pharo-users] NativeBoost : optimisation of the machine code generation
Okey, I found the issue and it was me doing lazy benchmark: I had forgot a debug printing function in the C code, that I had removed between the benchs. Thanks again for your time ! Thomas. 2014-08-07 21:56 GMT+02:00 stepharo : > NativeBoost methods compiles native code only once (the first time they > are executed) and when sessionId changes (because you may be on a different > platform). > So this is already like that. The assembly code is cached in the method > literal. > > Stef > > On 7/8/14 17:25, Thomas Bany wrote: > >> Hi everyone, >> >> I'm trying to reduce the computation time of the following pseudo-code: >> >> - memory allocation (~40 doubles) >> - object heap to C heap copying >> - NativeBoost call (nbCall:) >> - memory freeing >> >> The time profiling results are bellow: >> >> - 24*3600 calls : > 1 minute >> - 24*3600 calls with only memory allocation and copying : < 1 second >> - 1 call with a 24*3600 loop inside de C code : < 1 second >> >> So it appears that the very coslty step is the transition from Pharo to >> C. And I was wondering if it was possible to drasticly reduce this time by >> doing something like, generate the the machine code once and call it >> multiple time ? >> >> Thanks in advance ! >> >> Thomas. >> > > >
Re: [Pharo-users] FFI structs
Hi Annick ! I'll explain first why you got the error. The assignment time: ’05:45’ failed because you tried to put an array of char (of size 5*sizeof(char)) inside an address. At some point, you need to allocate the memory that will hold the data. In your case, you can do it quite easily with the class-side method #fromString: of class NBExternalAdress. This will return a pointer, which you can assign to the field of your struct. Regarding what you really want to do, having a char[5] field in your struct, I'm not totaly sure how you can do it with NativeBoost. A C struc is just a chunk of memory with a well defined size, so if you want to specify a field as a char[5], you must have a type that match that size. It does not look like the field parser of NBExternalStruct can do it dynamicaly. You could maybe hard code it by subclassing NBExternalType into NBExternalArrayOf5Char, with a valueSize of 5. As a final word, be wary of where you have allocated your objects, whether it is in object-space (#new), or in C heap (#externalNew). The first is garbage collected so the address are volatile, but you bare the duty of freeing the memory in the second. 2014-10-29 12:18 GMT+01:00 stepharo : > did you read the NativeBoost tutorial on the PharoForTheEntreprise book? > If you do please report potential mistakes so that we can improve. > > > > On 29/10/14 05:59, Annick Fron wrote: > >> I I have a C struct with a char* >> >> struct result { >> char* time } >> >> I define an ExternalStructure in FFI , with one field of type char* (note >> that the syntax char [5] is not accepted ! ). >> >> defineFields generates the accessors time and time: >> >> If I use >> time: ’05:45’ >> >> I get an error. >> How do I set a string value in an ExternalStructure ? >> >> Annick >> >> >> >> >> >> > >
Re: [Pharo-users] FFI structs
Oops, sorry, I was misslead by Steph reply. Some of the comments might still hold. For the *time: ’05:45’* code to work, you would need FFI to handle all the hassle of memory management and actually allocate the memory for 5 characters and copying it. I never used FFI but I doubt it does this. Looking at FFI library, you both have ExternalAddress (for the struct with char*) and ExternalType (for the struct with char[5]) that you can use. For the later solution, it still looks like you should define a specific 5 bytes ArrayOf5Char type. 2014-10-29 18:34 GMT+01:00 Annick Fron : > I can’t use NativeBoost on the Raspberry, I would be glad if I could !!! > > > Le 29 oct. 2014 à 12:18, stepharo a écrit : > > > did you read the NativeBoost tutorial on the PharoForTheEntreprise book? > > If you do please report potential mistakes so that we can improve. > > > > > > On 29/10/14 05:59, Annick Fron wrote: > >> I I have a C struct with a char* > >> > >> struct result { > >> char* time } > >> > >> I define an ExternalStructure in FFI , with one field of type char* > (note that the syntax char [5] is not accepted ! ). > >> > >> defineFields generates the accessors time and time: > >> > >> If I use > >> time: ’05:45’ > >> > >> I get an error. > >> How do I set a string value in an ExternalStructure ? > >> > >> Annick > >> > >> > >> > >> > >> > > > > > > >