Wednesday, May 14, 2014

RBS Drools (PART I, BASICS)

Rule-based systems - წესებზე/ბრძანებებზე დაფუძნებული სისტემა–  ძირითადად ისეთი ამოცანების გადაჭრაში გამოიყენება სადაც  ხელოვნური ინტელექტია საჭირო ან მძლავრი გამოთვლებია განსახორციელებელი. მაგალითად:  მგზავრობა მაქსიმალურად ბევრ ქალაქში ისე რომ მაქსიმალურად ცოტა თანხა დავხარჯოთ, ჭადრაკი ან თუნდაც სუდოკუ...

RBS–სათვის ბევრი პროექტები არის შექმნილი, ერთერთი არის Jboss Drools. ეს გახლავთ openSource პროექტი, რომელსაც სხვადასხვა შვილობილი (sub) პროექტები გააჩნია – Drools Expert, Drools Fusion, Drools Guvnor, Drools Planner და ასე შემდეგ.

გამახსენდა კიდევ Scala, ან IBM –ს აქვს Jrules პროექტი. Jrules ფასიანია, თუ ფული არ გვაქვს, უბრალოდ უნდა დავკმაყოფილდეთ იმით რაც გვაქვს. ამჯერად ამ სტატიაში Drools ზე ვისაუბრებთ.

სინტაქსი


 
rule "HelloPersons" 
  when 
       Person( firstName == "mariam" ) 
  then 
     // შესრულება
end  

მარტივი სინტაქსია. თუ სახელი ექვივალენტურია მარიამის, მაშინ
then ში გადავდივართ. კომპილერი ჭკვიანია და იცის რომ == იგივეა რაც String.equals

Person კლასის სხვა ველების შემოწმებაც შეგვიძლია და ასეთი სინტაქსი გვექნება:

 
rule "CheckPerson" 
when
    p: Person(age >= 18, country == "Georgia", nick: nickName)
then
    System.out.println( "Hello Mariam" );
end


ამ შემთხვევში p  არის reference variable.  აქვე პერსონის ობიექტიდან nickName ველი ამოვიღე და nick ცვლადში ჩავწერე (რათქმაუნდა  სქოუფი შეზღუდული აქ ამ ცვლადს).


პროგრამის გასაშვებად 2 გზა გვაქვს. პირველი ესაა ფლაგინის დაყენება IDE ში.

ვერსიები შეგიძლიათ აქედან ამოირჩიოთ:
 
http://download.jboss.org/drools/release/

თუმცა მე ყოველთვის ბოლო განახლებულს ვიღებ, ანუ შეგიძლიათ დააინსტალიროთ ეკლიფსში შემდეგი ლინკიდან :
 
http://download.jboss.org/drools/release/latest/org.drools.updatesite/ 


მეორე გზაა მავენის (ანუ იგივე მავნე) დეფენდენსებში დავამატოთ:

 
<dependency> 
        <groupId>org.drools</groupId> 
            <artifactId>drools-compiler</artifactId>
            <version> [ვერსია]</version> 
        </dependency> 
<dependency> 



rule ბის დასაწერად შექმენით სახელი.drl ფაილი რესურსებში. გასაშვებად კი Drools და jBPM ის მიერ შემოთავაზებული KIE API გამოგვადგება.


KieServices ks = KieServices.Factory.get(); 
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules"); 
 
Person p= new Person();

...     

kSession.insert(p); 
kSession.fireAllRules(); 


განვიხილოთ  ცოტა დახვეწილი მაგალითი. მაგალითად, ფიბანაჩის მიმდევრობაზე:

ჩვენ ვიცით რომ
 F(n)=F(n-1) + F(n+2)
ამასთან
 F(1) =1, და F(2)=1;



 public static class Fibonacci {

  private int sequence;
  private long value;

  public Fibonacci(int sequence) {
   this.setSequence(sequence);
   this.setValue(-1);
  }
   //... 
 } 


თავიდან  -1 მნიშვნელობები მივანიჭოთ  (–1 ით ავღნიშნოთ   ჯერ გამოუთვლელი მნიშვნელობები  )

rule "ფიბანაჩის ობიექტების შექმნა"
    when
        f : Fibonacci ( value == -1 )
        not ( Fibonacci ( sequence == 1 ) )   
    then
        insert( new Fibonacci( f.sequence - 1 ) );
        System.out.println( "recurse for " + f.sequence );
end



when –> თუ  Fibonacci ობიექტში მნიშვნელობა არის -1 (ჩვენ შექმნისას –1 მივანიჭეთ, შესაბამისად არის), მაშინ –> შევქმნათ ახალი ობიექტი , ერთით ნაკლები მიმდევრობის ნომრით.  


 rule "F(1) , F(2) ის ინიციალიზება"
    when
        f : Fibonacci(  sequence==1 || ==2, value == -1  ) 
    then
            modify ( f ){
         value = 1
     };
        System.out.println( f.sequence + " და " + f.value ); 
end



ყველა შემთხვევაში ვიცით რომ 1 –ს უდრის F(1) , F(2). ამიტომ: როცა  sequence==1 ან  sequence==2 , მაშინ გადავაკეთოთ მნიშვნელობები 1 ით. ამასთან value == -1 პირობაც დავამატოთ, თორემ ჩავიციკლებით.


და ბოლოს გამოვთვალოთ:

rule "გამოთვლა"
    when
        f1 : Fibonacci( s1 : sequence, value != -1) 
        f2 : Fibonacci( s2: sequence == (s1+1), value != -1 )
        f3 : Fibonacci( s3 : sequence == (f1.sequence+2 ), value == -1 )             
    then   
        modify ( f3 ) {
          value = f1.value + f2.value
         };
        System.out.println( s3 + " == " + f3.value ); 
end 



შედეგი
1 = 1
2 = 1
3 == 2
4 == 3
5 == 5
6 == 8
7 == 13
8 == 21
9 == 34
10 == 55
11 == 89
12 == 144
13 == 233
14 == 377
15 == 610
16 == 987
17 == 1597
18 == 2584
19 == 4181
20 == 6765
21 == 10946
22 == 17711
23 == 28657
24 == 46368
25 == 75025
26 == 121393
27 == 196418
28 == 317811
29 == 514229
30 == 832040
31 == 1346269
32 == 2178309
33 == 3524578
34 == 5702887
35 == 9227465
36 == 14930352
37 == 24157817
38 == 39088169
39 == 63245986
40 == 102334155
41 == 165580141
42 == 267914296
43 == 433494437
44 == 701408733
45 == 1134903170
46 == 1836311903
47 == 2971215073
48 == 4807526976
49 == 7778742049
50 == 12586269025
51 == 20365011074
52 == 32951280099
53 == 53316291173
54 == 86267571272
55 == 139583862445
56 == 225851433717
57 == 365435296162
58 == 591286729879
59 == 956722026041
60 == 1548008755920
61 == 2504730781961
62 == 4052739537881
63 == 6557470319842
64 == 10610209857723
65 == 17167680177565
66 == 27777890035288
67 == 44945570212853
68 == 72723460248141
69 == 117669030460994
70 == 190392490709135
71 == 308061521170129
72 == 498454011879264
73 == 806515533049393
74 == 1304969544928657
75 == 2111485077978050
76 == 3416454622906707
77 == 5527939700884757
78 == 8944394323791464
79 == 14472334024676221
80 == 23416728348467685
81 == 37889062373143906
82 == 61305790721611591
83 == 99194853094755497
84 == 160500643816367088
85 == 259695496911122585
86 == 420196140727489673
87 == 679891637638612258
88 == 1100087778366101931
89 == 1779979416004714189
90 == 2880067194370816120
91 == 4660046610375530309
92 == 7540113804746346429 
...
...
...

Saturday, December 21, 2013

ProtoBuf & Thrift



Protocol Buffer არის გუგლის ენა  - მექანიზმი დასასერიალიზირებადი მონაემებისათვის. სხვა სიტყვებით რომ ვთქვათ, საშუალებას გვაძლევს მარტივად და სწრაფად ვიმუშაოთ სტრუქტურიზირებულ მონაცემებთან.  წარმოიდგინეთ XML დოკუმენტი. XML ზე უფრო პატარა გვაქვს  JSON. უფრო პატარას, უფრო სწრაფს და უფრო მარტივს კი გუგლის გვთავაზობს(binary არის ოღონდ).  ერთხელ ვწერთ, თუ როგორი სტრუქტურა გვინდა, შემდეგ კი შესაძლებლობა გვაქვს მონაცემები ჩავწეროთ ან წავიკითხოთ.  ამასთან გვაქვს საშუალება,  სხვადასხვა ენებში მუშაობისა - Java, C++,  Python.

ტესტირებისთვის ჯავას ობიექტი დავასერიალიზე, დაახლოებით 500 byte ზომის გამომივიდა, ProtoBuf ით კი ბაინარი დატა 50 byte.

ამ მექანიზმს, ვისაც ნანახი გაქვთ, Google App Engineც იყენებს, და სხვა გუგლის სერვისები. საკმაოდ ფართოდ გამოყენებადია.

ალტერნატივებიც არსებობს, მაგალითად  Apache Thrift, რომელიც FB-მ შექმნა. ორივე რაღაცით არის კარგი. მაგალითად Thrift ისგან განსხვავებით, პროტოკოლ ბუფერით დასერიალიზირებული მონაცემები 30% ით უფრო მცირე არის. სამაგიეროდ, Thrift-ს სტრუქტურა მეტად დახვეწილი აქვს, მაგალითად შესაძლებელია Map ის აღწერა. კიდე ერთი განსხვავება ის არის რომ Thrift ში პირდაპირ არის ინტეგრირებული RPC , პროტოკოლ ბუფერში კი ცალკე არის გატანილი. ენების მხრიბ Thrift-ს შემდეგ ენებთან აქვს მუშაობის შესაძლებლოვა: Thrift: Java, C++, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, OCaml, ხოლო რაც შეეხება protobuf-ს მხოლოდ Java, C++, Python. და ბოლოს, რაც მთავარია Protobuf ვრცელდება BSD ლიცენზიით, Thrift-ს კი Apache License ადევს.


Sunday, December 8, 2013

Mapping Persistent Objects

Mapping Persistent Objects

ამ სტატიაში ვისაუბრებთ თუ როგორ ხდება ენთით ბინების  რელაციურ ბაზაში მოთავსება. შევეცდები, ყველაზე მნიშვნელოვან საკითხებზე ვისაუბრო. რასაც ვერ მოვასწრებ, შემდეგ სტატიაში შემოგთავაზებთ. დავიწყოთ.

@javax.persistence.Entity
@Entity ანოტაცია ფერსისთენს პროვაიერს ეუბნება, რომ შესაბამისი კლასი უნდა შეინახოს ბაზაში. ასე გამოიყურება ეს ანოტაცია:

როგორც ვხედავთ, აქ გვაქვს name() მეთოდო მხოლოდ. თუ სახელს არ გადავცემთ , დეფაულთად აიღებს ბინის სახელს.

@javax.persistence.Id 
განსაზღვრავს, თუ კლასის რომელი ველი იყოს ბაზაში promary key.
პატარა მაგალითი:


შესაძლებელია XML შიც გავაკეთოთ იგივე (persistence.xml ში).
მაგალითად:

@javax.persistence.GeneratedValue
რაც შეეხება primary key ს, შეგვიძლია ჩვენ ჩვენთვითონვე განუსაზღვროთ, ან საშვალება მივცეთ რომ თვითონვე დაგენერირდეს.
ასე გამოიყურება ჩვენი შესაძლებლობები:

როგორც ვხედავთ, დეფაულთად AUTO გვიყენია. დანარჩენებზე 3 ზე, დეტალური გარჩევა შეგიძლიათ იხილოთ ამ ლინკზე. მარტივი მაგალითი:

@javax.persistence.Table
ენთითი მენეჯერს ვეუბნებით რომ შესაბამისი ანოტაციის მნიშვნელობა ეხება რელაციური ბაზის ცხრილს. კერძოდ მაგალითად ფხრილის სახელის განსასაზღვრავად.
მთლიანად კი ასე გამოიყურება:

@javax.persistence.Column
სვეტებზე სამუშაო ანოტაცია. სულ ეს მეთოდები გვაქვს:


რელიციური ბაზები ვინც იცის, ადვილად მიხვდება ყოველივეს. მაგალითად, name განსაზღვრავს სვეტის სახელს.  table გამოიყენებას ახლა არ გავნმარტავ დეტაულად, თორე სხვა თემაზე მომიწევს გადახტომა- კერძოდ Multitable მეფინგის დროს გამოიყენება. მაგალითად, თუ გვინდა რაღაც ველები პარალელურად სხვა ცხრილშიც ჩავწეროთ. VARCHAR ის ზომას length განსაზღვრავს. დანარჩენიც ადვილი მისახვედრია ვინც რელაციური ბაზები იცით და აღარ გავაგრძელებ.




@Basic and FetchType

@Basic  ანოტაცია არის დეფაულთი მონაცემების ჩამწერი შემდეგი ტიპის მონაცემებისთივს:  java.lang.String, byte[], Byte[], char[], Character[], java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time ,  java.sql.Timestamp .

არ არის საჭირო ჩვენ ვუთხრათ ფერსისთენს მენეჯერს თუ როგორ ჩაწეროს მონაცემები, ის ავტომატურად ჩაწერს ისე როგორც საჭიროდ ჩათვლის.

აგერ ვიხილოთ ჩაწერის სახეებიც.



თუ fetch() ატრიბუტი არის LAY, შესაბამისი ფროფერთის ინიციალიზება არ მოხდება მანამ, სანამ მასზე წვდომას არ მოვახდენთ.   თუმცა აქ ერთი დეტალია გასათვალისწინებელი, ზოგადად @basic ანოტაცია არ არის პირდაპირ და ცალსახად განმსაზღვრელი თუ როგორ ვამუშაოთ პროგრამა. ეს უფრო მიმათითებელი არის, რომელიც შესაძლოა შესრულდეს სხვანაერადაც. ზოგმა JPA -ს იმპლემენტაციამ შეიძლება ეს აღიქვას, როგორც პირდაპირ განსაზღვრულად, ზოგმა შეიძლება არა. ანუ იმას ვამბობ რომ შეიძლება LAZY მივუთითოთ მაგრამ ინიციალიზება მაინც გაუკეთოს( ანუ EAGRLY სავით მოიქცეს). ეს მხოლოდ იმიტომ , რომ ოპტიმიზაციის გამო კარგად იმუშაოს - თვითნ ხვდება რომელი არის უკეთესი.
მოვიყვანოთ მაგალითი

XML შიც შეიძლება იგივე გავაკეთოთ:

@Temporal

საშუალებას გვაძლევს, რომ დამატებითი ინფორმაცია მივცემთ ფერსისთენს პროვაიდერს java.util.Date ან java.util.Calendar ზე. ანუ ამ ანოტაციის წყალობით შეგვიძლია შევინახოთ ბაზაში DATE, TIME, TIMESTAMP. მაგალითად გვინდა შევინახოთ ენთითს შექმნის თაღირი. ამაზე მაგალითსაც შემოგთავაზებთ ქვემოთ (სათითაოდ რომ არ ვწერო @Lob ზე და @Enumarated-ზე, ერთად დავწერ).

@Lob

ზოგჯერ არის შემთხვევები, როდესაც დიდი ინფორმაცია გვაქვს შესანახი ბაზაში. ამისათვის JDBC ში არის, მაგალითად, სპეციალური ტიპები ობიექტებისთვის. მაგალითად, ჩვენ ვიცით რომ java.sql.Blob არის binary მონაემებისთვის, ხოლო java.sql.Clob არის character მონაცემებისათვის. javax.persistence.Lob ანოტაცია არის სწირედ იმისთვის რომ შევინახოთ ესეთი ტიპის დიდი მონაცემები. (მაქალითს ქვემოთ დავწერ)

 @Enumerated

ეს ანოტაცია საშვალებას გვაძლევს შევიანახოთ ენამის ტიპის მონაცემები ბაზაში.

ამ ბოლო სამ ანოტაციაზე მაგალითი კი ეს არის:

ახლა მოვრჩები წერას :) კიდევ აუცილებელი და მნიშვნელოვანი საკითხებია @Embeddable ობიექტები,   Primary-Key კლასები, რელაციები ბაზებს შორის და ასე შემდეგ.   როცა დრო მექნება გავაგრძელებ წერას:)


Monday, November 18, 2013

PRS MNG FlushModes

ამ სტატიაში ვისაუბრებთ FlushModeType-ზე.














ენამი გამოიყურება შემდეგნაირად:

public enum FlushModeType{
 AUTO,
 COMMIT
}

შესაბამისი მისამრთი:
################################
javax.persistence.FlushModeType
################################


იმის შემდეგ რაც persist(), merge(), remove() გამოვიყენებთ, ცვლილებები ბაზაში არ აისახება მანამ სანამ ენთითი მენეჯერი არ გააუკეთებს flush-ს. ჩვენ შეგვიძლია იძულებით მოვახდინოთ დასინქრონიზირება, თუ გამოვიყენებთ flush() მეთოდს. ზოგადად, დეფაულთად ისე არის კონფიგურირებული რომ, flush ხდება მაშინ, როდესაც ტრანზაქცია მთავრდება და ასევე მაშინაც, როდესაც რაიმე ქუერის ეგზექიუთს გავუკეთებთ - აქ დასაზუსტებელია query ში რას ვგულისხმობთ და რა გამონაკლისები არსებობს: მაგალითად, მოვახდინეთ რაიმე ობიექტის persist და შემდეგ find() ით დავაბრუნოთ შესაბამისი ობიექტი. შედეგი ის იქნება , რომ null დაგვიბრუნდება. find და getReference არიან ისეთი ტიპები, რომლებიც არ ახდენენ ბაზაში ცვლილებებს,
შესაბამისად, flush იც არ იქნება გამოძახებული, მის შესრულების შემდეგაც. აქ, getReference() ვახსენე, და ბარემ განვმარტავ რა განსხვავებაა ამათ შორის.

 განსხვავება იმაში მდგოამრეობს რომ თუ find() -ს ვიყენებთ, თუ ბაზაში შესაბამისი ჩანაწერი არ მოიძებნა null დაბრუნდება,  getReference()-ს შემთხვევაში  კი javax.persistence.EntityNotFoundException-ს ისრვრის.

როდესაც შეეხეაბაზ FlushModeType-ს, დეფაულთად AUTO აყენია. ყველაფერს თავისი გამოყენება აქვს, გააჩნია რა ამოცანა გავაქვს გადასაჭრელი, შესაბამისად შეიძლება AUTO გამოგვადგეს, შესაძლოა COMMIT. ამიტომაც გვაქვს setFlushMode(), რომლის საშუალებითაც შეგვიძლია ვაკონტროლოთ flush -ის მუშაობა. მაგალთად, თუ ბევრი აბდეიტებია გასაკეთებელი, შეგვიძლია ფერფორმენსის მიზნით აბდეიტი ერთ batch ში გავაკეთოთ, ამისთვის სწორედ COMMIT გვჭირდება. მოვიყვანოთ მაგალითიც.




Saturday, November 9, 2013

EX $PATH Linux

წარმოვიდგინოთ სიტვაცია როდესაც პროგრამა დავაყენეთ და კლასფასში არ ჩაჯდა, მაგალითად:
linux:~ #  aming-ng 

და გვეუბნება:

#If 'airmon-ng' is not a typo you can use 
command-not-found to lookup the package that contains it, 
like this:  cnf airmon-ng 


პრობლემა ორიდან ერთია, არ პროგრამა არ მიყენია ან კლასფასში არ მიზის[ხდებახოლმე].

მოვძებნოთ სად გვიგდია ჩვენი airmon - [ან თუ არის საერთოდ]

linux:~ #  find / -name airmon-ng
/usr/local/sbin/airmon-ng


ისე მოსაძებნად ესეც შეგვიიძლია

linux:~ #  locate airmon-ng 


   

კარგია, ახლა კლასფასი ვნახოთ:

 linux:~ #  echo $PATH
#/home/vakhoq/bin:/usr/local/bin
:/usr/bin:/sbin:/usr/sbin:/bin
:/usr/bin/X11:/usr/X11R6/bin
:/usr/games 



როგორც ჩანს ჩვენი პროგრამ არ ზის. ოკ ჩავსვათ მარტივად:

linux:~ #  export PATH=$PATH:/usr/local/sbin


სულ ეს იყო, შევამოწმოთ ფასი:

linux:~ # airmon-ng

და მივიღეთ აუთფუთი:
Interface       Chipset         Driver
wlan0                   ath9k - [phy0]

Tuesday, November 5, 2013

EJB PersistenceContextTypes



EJB 3.X ში გვაქვს extended persistence context და  მეორეა transaction-scoped.  თუ მეორეზე გვაქ საუბარი, ბინის ინსტანსი არის წვდომადი [managed] მანამ სანამ ტრანზაქციაში ვართ [ტრანზაქცია როგორც კი მორჩება, წვდომა აღარ გვექნება, ამ მდგოამრეობას detached-ს ვუწოდებთ]. ანუ როგორ კი ტრანზაქცია დამთავრდება პერსისთენს ობიექტები გახდეაბიან detached.

თუმცა სხვაგვარად გვაქვს საქმე  extended scoped კონტექსტში. მიუხედავად ტრანზაქციის დასრუელბისა, ენთითის ინსტანსი რჩება წვდომადი კვლავ - ყველა ობიექტის ისნტანცი რჩება წვდომადი.

ანუ ეს ორი ვარიანტი გვაქვს:

PersistenceContextType.EXTENDED
PersistenceContextType.TRANSACTION

მაგალითად, შევქმნათ Stateful (!)) ბინი.

@Stateful
public class ShoppingCartBean implements ShoppingCart{

   @PersistenceContext(type=PersistenceContextType.EXTENDED)
   EntityManager em; 

   private Account account

   public void addAccount(){
      account= new Account();
      account.setName("valhtang");
      account.setAge("21");
      em.persist(account)
   }


   public void updateAge(){
      account.setAge("22");
   }

}
თუ, EXTENDED არ გვექნებოდა, როდესაც addAccount შესრულდებოდა, ტრანზაქციაც მორჩებოდა, და updateAge სთვის შეცვლიდა მხოლოდ detached entity ინსტანსს, და რათმქაუნდა ეს ბაზაზე არ მოახდენდა გავლენას. ამ შემთხვევაში კი, ტრანზაქციის დასრულების შემდეგაც გვაქვს წვდომა.

kernel/debug/vgaswitcheroo


ლეპტოპობი, რომლებსაც ჰიბრიდული ვიდეო კარტა აქვთ [იგულისხმება, როდესაც  2 ვიდეო კარტა არის ლეპტოპზე, ძმლავრი მხოლოდ მაშინ ირთვება, როდესაც ამის რესურსი არის საჭირო. მიზანი ამ ვიდეო კარტების შექმნისა იყი ის რომ, დაეზოგად ბატარეის რესურსი. ცხადია GT 550 M რომ იყოს სულ ჩართული, ერთ საათიც არ დაჭირდება ბატარეა მთიანად რომ დასვას], საჭიროებენ ოპტიმიზაციას.

ერთერთი საშვალება ეკონომიის გასაკეთებლად არის პროექტი სახელად Bumblebee რომელიც რათქმაუნდა იდეალური არ არის, თუმცა ნელნელა ახალ ფუნქციონალურობას უმატებენ, და თანდათან უკეთესი ხდება. მეორე საშვალება კი ეს არის მექანიზმი კერნელისა, რომელსაც vga_switcheroo ვუწოდებთ. დავიწყოთ განხილვა:


vgaswitcheroo საშვალებით ადვილად შეგვიძლია ვაკნტროლოთ ჩვენი ვიდეოკარტების მუშაობა). vgaswitcheroo არის მექანიზმი კერნელში [ისე ზოგს სისტემა linux გონია, არადა მხოლოდ კერნელია ეს სისტემა კი Gnu/Linux] რომლის საშვალებითაც შეგვილია გადავერთოდ სხვადასხვა ვიდეოკარტებზე [ან ერთი გავთიშოთ ან მეორე და ასე შემდეგ]

იმის გასაგებად თუ რა ვიდეოკარტები გაქვთ შეგიძლიათ მარტივად მოვძებნოთ:

lspci | grep 'VGA'

და შედეგიც გვაქვს:
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09)
01:00.0 VGA compatible controller: NVIDIA Corporation GF108 [GeForce GT 540M] (rev ff)
შეგვიძლია ასეც შეცამოწმოთ ჩვენი ვიდეოკარტები:
lspci -vnn | grep '\''[030[02]\]'

-ეს მექანიზმი ყველა გნუ/ლინუქსში არის ჩადებული?
- გააჩნია ვიდეო კარტის რა დრაივერს იყენებს. მხოლოდ იმ შემთხვევაში არის თუ უფენსორს დრაივერს იყენებს სისტემა. კერძოდ nouveau, radeonს. თუ Nvidiaსას იყენებს ან fglrx-ს, მაშინ არ აქვს. და შეგვიძლა შევამოწმოთ კერნელში არის თუ არა ჩადებული შემდეგნაირად:

grep -i switcheroo /boot/config-*
CONFIG_VGA_SWITCHEROO=y




შეგვიძლია შევქმნათ სკრიპტი, რომელსაც ხელით გავუშვებთ ხოლმე.
vakhoq@linux:~> cd [dir]>
vakhoq@linux: [dir]>  touch hybrid.sh
vakhoq@linux: [dir]>  vi hybrid.sh

შიგნით ვწერთ მაგალითად ვიდეოკარტის გათიშვას.

###################################################
#!/bin/sh
# მხოლოდ გავთიშოთ მეტი არაფერი echo OFF > /sys/kernel/debug/vgaswitcheroo/switch ####################################################

ვინახავთ :wq საშვალებით. მოკლედ, Nvidia ვთიშავთ, რათა ინტეგრირებულზე იყოს მხოლოდ ჩვენი ლეპტოპი. (გაითვალისწინეთ ფერმიშენები იქნება საჭირო ამ სკრიპტის გასაშვებად. ამიტომ sudo ან su გამოიყენეთ)
პ.ს საერთოდოდ rc.local ში შეგიძლიათ ჩააგდოთ სკრიპტი. ან after.local  ში , გააჩნია რომელ დისტროს იყენებთ. rc.local უბუნტუში after.local კი OpenSuse ში).



ამასთან სტატუსების შემოწმება, თუ რა მდგომარეობაშია ჩვენი ვიდეო კარტა შეგვიძლია შემდეგნაირად:
cat /sys/kernel/debug/vgaswitcheroo/switch
შევამოწმოთ რამდენად ოპტიმალურია ჩვენი სამუშაო.

ამისთვის ჯერ ჩავთოთ/გამოვრთოთ ვიდეოკარტაზე წვდომა, შემდეგ სტატუსები გამოვაჩინოთ და acpi საშვალებით დროებიც ვნახოთ  (დებიანზე apt-get install acpi , suse  zypper install acpi და ასე შემდეგ)

#############################################################
vakhoq@Gnulinux:~> su
Password: ******

Gnulinux:/home/vakhoq# echo ON > /sys/kernel/debug/vgaswitcheroo/switch Gnulinux:/home/vakhoq # cat /sys/kernel/debug/vgaswitcheroo/switch 0:IGD:+:Pwr:0000:00:02.0 1:DIS: :Pwr:0000:01:00.0 linux:/home/vakhoq# acpi Battery 0: Discharging, 85%, 00:55:07 remaining
Gnulinux:/home/vakhoq# echo OFF > /sys/kernel/debug/vgaswitcheroo/switch Gnulinux:/home/vakhoq # cat /sys/kernel/debug/vgaswitcheroo/switch 0:IGD:+:Pwr:0000:00:02.0 1:DIS: :Off:0000:01:00.0 Gnulinux:/home/vakhoq# acpi Battery 0: Discharging, 85%, 01:35:12 remaining #############################################################


როგორც ხედავთ საკმაოდ კარგი შედეგები გვაქვს.
ახლა სათითაოდ განვამრტოთ რას ნიშნავს გამონატილი შედეგები
IGD - ნიშნავს Integrated Graphic Device (ძირითადად Intel)
DIS: denotes DIScrete graphic device (nVidia ან ATI)
+ რომელსაც უწერია, ნიშნავს რომ ის ვიდეოკარტაა აქტიური.
დანარჩენს აღარ გავნამრტავ, ისედაც ცხადია. :)