Code to compare two libraries for cells and pins

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • blackgoat
    New Member
    • Jan 2010
    • 33

    Code to compare two libraries for cells and pins

    I am totally new to unix and perl. Although I have gone thtough some basics of both, I am still not quite comfortable with using them. I have received the following assignment. Can anyone pls help:
    [
    filename: compareLib.pl

    Lib1
    Cell : AND1
    A1 A2 Y
    Cell : INV1
    A Z

    Lib2
    Cell : AND1
    A B Y
    Cell : INV2
    A Z

    expected o/p:
    compareLib.pl <Lib1> <Lib2>
    - INV1 missing in LIB2
    - INV2 missing in LIB1
    - AND1/A1 missing in LIB2
    - AND1/A2 missing in LIB2
    - AND1/A missing in LIB1
    - AND1/A missing in LIB1



    open Lib1
    match for cell string : get cell name in a variable
    match for pin names : $hash1{$cell}{$ pin}=1;


    open Lib2
    match for cell string : get cell name in a variable
    match for pin names : $hash2{$cell}{$ pin}=1;

    Iterate through hash1 and check is exists in hash2 or not. If not report missing...
    Iterate through hash2 and check is exists in hash1 or not. If not report missing...
    ]

    I shall be great full for any help on this.
    thanx
  • blackgoat
    New Member
    • Jan 2010
    • 33

    #2
    somebody pleeeese help me!

    Comment

    • blackgoat
      New Member
      • Jan 2010
      • 33

      #3
      Halp!!

      i have the following code pls somebody reply and tell my how i can use it. pleeeeeeeese!!

      Code:
      # read all of file1
      open(F,&quot;file1&quot;)||die;
      while(<F>){
        $file1hash{$_}=1; # into a hash array
      }
      close(F);
      
      # create the output file
      open(OF,&quot;out.file&quot;)||die;
      # then read through file2
      open(F,&quot;file2&quot;)||die;
      while(<F>){
        print OF $_ unless defined($file1hash{$_});
      }
      close(F);

      Comment

      • chaarmann
        Recognized Expert Contributor
        • Nov 2007
        • 785

        #4
        Have you written this code yourself? If not, do you understand it?
        Do you also understand the line "match for pin names : $hash1{$cell}{$ pin}=1;" in your assignment? Can you program Perl and do you understand how to use hashes?
        It seems not. (Please correct me if I guesssed wrong. Then read no further on). But if I am right, the best help I can give you is to google for a perl tutorial and execute it.
        Remember:
        We are not here to make your homework or give you spoonfeed code (see forum guidelines), even if you are begging more than once.
        But we will happily help you with your own code listed here.

        So what is the problem with the code you listed ? You wrote, you don't know how to use it. So what does that mean? That you don't know how to run perl programs in general, or that you don't know what the code is doing? The latter one implies that you didn't write the code by yourself, but copied it from somewhere.

        Here's more help:
        To solve your task, you need following knowledge:
        - how to run a perl program
        - how to use arrays in perl (how to enumerate, assign and access elements)
        - how to open files and read the content as string
        - how to compare strings

        Please do the corresponding tutorials and come back here with your own code you did after that.

        Comment

        • blackgoat
          New Member
          • Jan 2010
          • 33

          #5
          thank you so much for your reply.
          i really appreciate the fact that you discourage spoon feeding and push for self attempt.
          i am to do a project that requires some assistance of perl. i havent touched perl before and logged on to your forum to get some help that could get me started so as to speed up.
          i know i can always invest time in tutorials and learn it my self. since this is also what you suggest i guess i will just have to bear with the delay and go for it!
          well thanks a lot again!

          Comment

          • blackgoat
            New Member
            • Jan 2010
            • 33

            #6
            hi

            i have already potsed my assignment up there so u know what i have to do. i wonder if i could get any help with the following. i figured i could iterate through the hashes in two possible ways:

            i can use use the for each loop like this:
            Code:
            foreach my $key ( keys %hash )
            {
              print "key: $key, value: $hash{$key}\n";
            }
            or i can use the while loop:
            Code:
            while ( ($key, $value) = each %hash )
            {
              print "key: $key, value: $hash{$key}\n";
            }
            but i can seem to figure which would optimize the solution.
            pls help.

            Thanks.

            Comment

            • chaarmann
              Recognized Expert Contributor
              • Nov 2007
              • 785

              #7
              Hi, I was very busy so a quick answer, more tomorrow.
              The second solution is not optimized, you should print $value instead of $hash{$key} so it doesn't do a timeconsuming search on the hash. You alread have the value, so just print it, why search again for it?
              If you change it this way, the second loop should be faster, especially on big hash-tables.

              if you don't need the value, but only the key, the first solution should be faster.

              This is a strong guess from my experience, I haven't done any performance checks to verify this.

              Comment

              • RonB
                Recognized Expert Contributor
                • Jun 2009
                • 589

                #8
                Benchmark - benchmark running times of Perl code


                If you run a benchmark test, I think you'll fine that the foreach loop is about 30% faster. But unless you're working with very large hashes, the difference will be within a few millionths to a few thousandths of a second

                Comment

                • blackgoat
                  New Member
                  • Jan 2010
                  • 33

                  #9
                  Thank you for that...
                  i will get back once i try something.
                  however you said there will be more tomorrow, so i shall be waiting!
                  Thanks again

                  Comment

                  • chaarmann
                    Recognized Expert Contributor
                    • Nov 2007
                    • 785

                    #10
                    Originally posted by RonB
                    If you run a benchmark test, I think you'll fine that the foreach loop is about 30% faster.
                    Ron, you are right. It seems that the search for a value inside a hash array by key isn't the bottleneck, it only makes it 7% slower. But why is it so much slower then?

                    I tested with the benchmark you gave, here are the results:
                    Code:
                                     Rate  test_while_hash  test_while  test_foreach
                    test_while_hash 1228/s          --           -6%        -43%
                    test_while      1314/s          7%            --        -40%
                    test_foreach    2172/s         77%           65%          --
                    My program:
                    Code:
                    use Benchmark qw(:all);
                    
                    sub test_foreach {
                    	my $key, $message;
                    	foreach $key ( keys %hash ) 
                    	{ 
                    		$message = "key: $key, value: $hash{$key}\n";
                    		# print $message;
                    	} 
                    };
                    
                    sub test_while {
                    	my $key, $value, $message;
                    	while ( ($key, $value) = each %hash ) 
                    	{ 
                    		$message = "key: $key, value: $value\n"; 
                    		# print $message;
                    	} 
                    };
                    
                    sub test_while_hash {
                    	my $key, $value, $message;
                    	while ( ($key, $value) = each %hash ) 
                    	{ 
                    		$message = "key: $key, value: $hash{$key}\n";
                    		# print $message;
                    	} 
                    };
                    
                    # main program
                    our %hash;
                    foreach my $number (1..1000) {
                    	$hash{"number$number" } = $number;
                    }
                    cmpthese(-1, {
                      'test_foreach' => \&test_foreach,
                      'test_while' => \&test_while,
                      'test_while_hash' => \&test_while_hash,
                    });
                    Remarks for OP:
                    This program generates an array of 1000 hash-values
                    %hash=("number1 " => 1, "number2" => 2, "number3" => 3);
                    and so on. Then it runs each of the subs "test_forea ch", "test_while ", "test_while_has h" until 1 second is over and counts how many times it was run. This value is shown as "Rate" in the statistics.

                    Comment

                    • RonB
                      Recognized Expert Contributor
                      • Jun 2009
                      • 589

                      #11
                      First, your code is missing
                      Code:
                      use warnings;
                      use strict;
                      If it were, you'd be getting several warnings and a number of compilation errors ending with "aborted due to compilation errors".

                      It is very important to include those pragmas in all scripts, including examples posted here.

                      The issue here is that the test that perl does at the start of each iteration of a while loop has more overhead than what is done when iterating over a list via for/foreach.

                      The precise details of that overhead is unknown to me, but you could probably find out some of those details by running it through strace. There are several CPAN modules that will show what's going on under the hood, but I haven't used them and don't recall their names.

                      Comment

                      • RonB
                        Recognized Expert Contributor
                        • Jun 2009
                        • 589

                        #12
                        I forgot to mention that the system specs and current load will impact the benchmark results. When I ran the test on my Windows box, I received roughly the same results as yours, but my fedora box was quite different.

                        Here's a corrected version and the results.
                        Code:
                        [root@rkb-2 ~]# cat chaarmann.pl
                        #!/usr/bin/perl
                        
                        use warnings;
                        use strict;
                        use Benchmark qw( cmpthese );
                        
                        my %hash;
                        foreach my $number (1..1000) {
                            $hash{"number$number" } = $number;
                        }
                        
                        cmpthese(-10, {
                          'test_foreach'    => \&test_foreach,
                          'test_while'      => \&test_while,
                          'test_while_hash' => \&test_while_hash,
                        });
                        
                        
                        sub test_foreach {
                            foreach my $key ( keys %hash ) {
                                my $message = "key: $key, value: $hash{$key}\n";
                            }
                        };
                        
                        sub test_while {
                            while ( my ($key, $value) = each %hash ) {
                                my $message = "key: $key, value: $value\n";
                            }
                        };
                        
                        sub test_while_hash {
                            while ( my ($key, $value) = each %hash ) {
                                my $message = "key: $key, value: $hash{$key}\n";
                            }
                        };
                        Code:
                        [root@rkb-2 ~]# ./chaarmann.pl
                                         Rate test_while_hash      test_while    test_foreach
                        test_while_hash 223/s              --             -9%            -23%
                        test_while      244/s             10%              --            -16%
                        test_foreach    290/s             30%             19%              --

                        Comment

                        • chaarmann
                          Recognized Expert Contributor
                          • Nov 2007
                          • 785

                          #13
                          I tested on a Sun Solaris Sparc Workstation, and got roughly the same performance results Ron got. That means the differences are not so big on Unix machines than on Windows machines.
                          I figured out that defining the variables with "my" before the loop is faster than defining them when they are used (although the latter one is better programming style regarding the usage scope of the variable).
                          Here the test "test_forea ch" ran 13% faster than "test_foreach2" .
                          Code:
                          sub test_foreach {
                          	my ($key, $message);
                          	foreach $key ( keys %hash ) 
                          	{ 
                          		$message = "key: $key, value: $hash{$key}\n";
                           	} 
                          };
                          sub test_foreach2 {
                          	foreach my $key ( keys %hash ) 
                          	{ 
                          		my $message = "key: $key, value: $hash{$key}\n";
                          	} 
                          };
                          This is just a code snipped.
                          Of course I put "use strict; use warnings;" at the begin of my file.

                          Perl-versions used:
                          Windows: perl v5.10.0
                          Solaris: perl v5.8.4

                          Comment

                          • chaarmann
                            Recognized Expert Contributor
                            • Nov 2007
                            • 785

                            #14
                            Let's get back to the OP's (BlackGoat) assignment.
                            Because BlackGoat doesn't give up and starts programming of his own, which is a very good character trait, I want to give him a quickstart with some code snippets:
                            You need following algorhithm:
                            1. read in from file, line by line:
                              Code:
                              open(FILE, "Lib1.txt") or die "Error";
                              while(defined(my $line = <FILE>)) { print $line};
                              close(FILE);
                            2. If the line starts with "cell :" then you know a name for a "cell" is following, else parse the line and split it into words (delimiter: space) to get all names for the "pins" of the current "cell". You can do that with the perl-function split() and some string comparisons.
                            3. store the words read in into a two-dimensional array $hash1{"cell_na me"}{"pin_name" }, which is a hash of hashes. Here is how I stored a "pin":
                              As you can see in the code below, in the outer hashtable, each key is a name of the "cell" and each value points to an inner hashtable that contains all the "pins" of this "cell". The keys of the inner hashes are the names of the "pins" and the values are counter values, that means how many times this name occurred.
                              This code snippet shows how to make such a hash and how to access or add its elements:
                              Code:
                              # definition of hash of hashes
                              my %hash1 = ("AND1" => {"A1" => 1, "A2" => 1, "Y" => 1}, "INV1" => {"A" => 1, "Z" => 1});
                              # ways to access and add new elements
                              print "Cell AND1, pin A1=".$hash1{"AND1"}{"A1"}."\n";
                              $hash1{"INV1"}{"Z"} = 3;
                              print "Cell INV1, pin Z=".$hash1{"INV1"}{"Z"}."\n";
                              $hash1{"NEW"} = {"X" => 4};
                              print "Cell NEW, pin X=".$hash1{"NEW"}{"X"}."\n";
                              print "Cell NEW, pin Y=".$hash1{"NEW"}{"Y"}."\n";
                              $hash1{"NEW"}{"Y"} = 7;
                              print "Cell NEW, pin Y=".$hash1{"NEW"}{"Y"}."\n";
                              This code snippet produces following output
                              Code:
                              Cell AND1, pin A1=1
                              Cell INV1, pin Z=3
                              Cell NEW, pin X=4
                              Use of uninitialized value in concatenation (.) or string at libTest.pl line 17.
                              
                              Cell NEW, pin Y=
                              Cell NEW, pin Y=7
                            4. do the same with the second file: read in all words and store them in $hash2{"cell_na me"}{"pin_name" }
                            5. after all is read in, you need to compare all keys of both hash1 and hash2 and print out the differences (One outside-loop to go throgh all cells and one inside-loop to go through all pins of a cell).

                            Comment

                            • blackgoat
                              New Member
                              • Jan 2010
                              • 33

                              #15
                              Thanks for helping out Sir.

                              Comment

                              Working...