- authors
- Jason Lowe-Power
Debugging SLICC Protocols
In this section, I present the steps that I took while debugging the MSI protocol implemented earlier in this chapter. Learning to debug coherence protocols is a challenge. The best way is by working with others who have written SLICC protocols in the past. However, since you, the reader, cannot look over my shoulder while I am debugging a protocol, I am trying to present the next-best thing.
Here, I first present some high-level suggestions to tackling protocol errors. Next, I discuss some details about deadlocks, and how to understand protocol traces that can be used to fix them. Then, I present my experience debugging the MSI protocol in this chapter in a stream-of-consciousness style. I will show the error that was generated, then the solution to the error, sometimes with some commentary of the different tactics I tried to solve the error.
General debugging tips
Ruby has many useful debug flags. However, the most useful, by far, is
ProtocolTrace
. Below, you will see several examples of using the
protocol trace to debug a protocol. The protocol trace prints every
transition for all controllers. Thus, you can simply trace the entire
execution of the cache system.

- RubyPort/RubySequencer
- See the details of sending/receiving messages into/out of ruby.
- RubyNetwork
- Prints entire network messages including the sender/receiver and the data within the message for all messages. This flag is useful when there is a data mismatch.
The first step to debugging a Ruby protocol is to run it with the Ruby random tester. The random tester issues semi-random requests into the Ruby system and checks to make sure the returned data is correct. To make debugging faster, the random tester issues read requests from one controller for a block and a write request for the same cache block (but a different byte) from a different controller. Thus, the Ruby random tester does a good job exercising the transient states and race conditions in the protocol.
Unfortunately, the random tester’s configuration is slightly different
than when using normal CPUs. Thus, we need to use a different
MyCacheSystem
than before. You can download this different cache
system file
here <../../_static/scripts/part3/configs/test_caches.py> and you
can download the modified run script
here <../../_static/scripts/part3/configs/ruby_test.py>. The test
run script is mostly the same as the simple run script, but creates the
RubyRandomTester
instead of CPUs.
It is often a good idea to first run the random tester with a single “CPU”. Then, increase the number of loads from the default of 100 to something that takes a few minutes to execute on your host system. Next, if there are no errors, then increase the number of “CPUs” to two and reduce the number of loads to 100 again. Then, start increasing the number of loads. Finally, you can increase the number of CPUs to something reasonable for the system you are trying to simulate. If you can run the random tester for 10-15 minutes, you can be slightly confident that the random tester isn’t going to find any other bugs.
Once you have your protocol working with the random tester, you can move on to using real applications. It is likely that real applications will expose even more bugs in the protocol. If at all possible, it is much easier to debug your protocol with the random tester than with real applications!
Understanding Protocol Traces
Unfortunately, despite extensive effort to catch bugs in them, coherence protocols (even heavily tested ones) will have bugs. Sometimes these bugs are relatively simple fixes, while other times the bugs will be very insidious and difficult to track down. In the worst case, the bugs will manifest themselves as deadlocks: bugs that literally prevent the application from making progress. Another similar problem is livelocks: where the program runs forever due to a cycle somewhere in the system. Whenever livelocks or deadlocks occur, the next thing to do is generate a protocol trace. Traces print a running list of every transition that is happening in the memory system: memory requests starting and completing, L1 and directory transitions, etc. You can then use these traces to identify why the deadlock is occurring. However, as we will discuss in more detail below, debugging deadlocks in protocol traces is often extremely challenging.
Here, we discuss what appears in the protocol trace to help explain what is happening. To start with, lets look at a small snippet of a protocol trace (we will discuss the details of this trace further below):
...
4541 0 L1Cache Replacement MI_A>MI_A [0x4ac0, line 0x4ac0]
4542 0 L1Cache PutAck MI_A>I [0x4ac0, line 0x4ac0]
4549 0 Directory MemAck MI_M>I [0x4ac0, line 0x4ac0]
4641 0 Seq Begin > [0x4aec, line 0x4ac0] LD
4652 0 L1Cache Load I>IS_D [0x4ac0, line 0x4ac0]
4657 0 Directory GetS I>S_M [0x4ac0, line 0x4ac0]
4669 0 Directory MemData S_M>S [0x4ac0, line 0x4ac0]
4674 0 Seq Done > [0x4aec, line 0x4ac0] 33 cycles
4674 0 L1Cache DataDirNoAcks IS_D>S [0x4ac0, line 0x4ac0]
5321 0 Seq Begin > [0x4aec, line 0x4ac0] ST
5322 0 L1Cache Store S>SM_AD [0x4ac0, line 0x4ac0]
5327 0 Directory GetM S>M_M [0x4ac0, line 0x4ac0]
Every line in this trace has a set pattern in terms of what information appears on that line. Specifically, the fields are:
- Current Tick: the tick the print is occurs in
- Machine Version: The number of the machine where this request is coming from. For example, if there are 4 L1 caches, then the numbers would be 0-3. Assuming you have 1 L1 Cache per core, you can think of this as representing the core the request is coming from.
- Component: which part of the system is doing the print. Generally,
Seq
is shorthand for Sequencer,L1Cache
represents the L1 Cache, “Directory” represents the directory, and so on. For L1 caches and the directory, this represents the name of the machine type (i.e., what is after “MachineType:” in themachine()
definition). - Action: what the component is doing. For example, “Begin” means the Sequencer has received a new request, “Done” means that the Sequencer is completing a previous request, and “DataDirNoAcks” means that our DataDirNoAcks event is being triggered.
- Transition (e.g., MI_A>MI_A): what state transition this action is doing (format: “currentState>nextState”). If no transition is happening, this is denoted with “>”.
- Address (e.g., [0x4ac0, line 0x4ac0]): the physical address of the
request (format: [wordAddress, lineAddress]). This address will
always be cache-block aligned except for requests from the
Sequencer
andmandatoryQueue
. - (Optional) Comments: optionally, there is one additional field to
pass comments. For example, the “LD” , “ST”, and “33 cycles” lines
use this extra field to pass additional information to the trace –
such as identifying the request as a load or store. For SLICC
transitions,
APPEND_TRANSITION_COMMENT
often use this, as we discussed previously <MSI-actions-section>.
Generally, spaces are used to separate each of these fields (the space between the fields are added implicitly, you do not need to add them). However, sometimes if a field is very long, there may be no spaces or the line may be shifted compared to other lines.
Using this information, let’s analyze the above snippet. The first (tick) field tells us that this trace snippet is showing what was happening in the memory system between ticks 4541 and 5327. In this snippet, all of the requests are coming from L1Cache-0 (core 0) and going to Directory-0 (the first bank of the directory). During this time, we see several memory requests and state transitions for the cache line 0x4ac0, both at the L1 caches and the directory. For example, in tick 5322, the core executes a store to 0x4ac0. However, it currently does not have that line in Modified in its cache (it is in Shared after the core loaded it from ticks 4641-4674), so it needs to request ownership for that line from the directory (which receives this request in tick 5327). While waiting for ownership, L1Cache-0 transitions from S (Shared) to SM_AD (a transient state – was in S, going to M, waiting for Ack and Data).
To add a print to the protocol trace, you will need to add a print with
these fields with the ProtocolTrace flag. For example, if you look at
src/mem/ruby/system/Sequencer.cc
, you can see where the
Seq Begin
and Seq Done
trace prints
come from (search for ProtocolTrace).
Errors I ran into debugging MSI
gem5.opt: build/MSI/mem/ruby/system/Sequencer.cc:423: void Sequencer::readCallback(Addr, DataBlock&, bool, MachineType, Cycles, Cycles, Cycles): Assertion `m_readRequestTable.count(makeLineAddress(address))' failed.
 It’s good to start simple!
gem5.opt: build/MSI/mem/ruby/network/MessageBuffer.cc:220: Tick MessageBuffer::dequeue(Tick, bool): Assertion `isReady(current_time)' failed.
I ran gem5 in GDB to get more information. Look at L1Cache_Controller::doTransitionWorker. The current transition is: event=L1Cache_Event_PutAck, state=L1Cache_State_MI_A, <next_state=@0x7fffffffd0a0>: L1Cache_State_FIRST This is more simply MI_A->I on a PutAck See it’s in popResponseQueue.
The problem is that the PutAck is on the forward network, not the response network.
panic: Invalid transition
system.caches.controllers0 time: 3594 addr: 3264 event: DataDirAcks state: IS_D
Hmm. I think this shouldn’t have happened. The needed acks should always be 0 or you get data from the owner. Ah. So I implemented sendDataToReq at the directory to always send the number of sharers. If we get this response in IS_D we don’t care whether or not there are sharers. Thus, to make things more simple, I’m just going to transition to S on DataDirAcks. This is a slight difference from the original implementation in Sorin et al.
Well, actually, I think it’s that we send the request after we add ourselves to the sharer list. The above is incorrect. Sorin et al. were not wrong! Let’s try not doing that!
So, I fixed this by checking to see if the requestor is the owner before sending the data to the requestor at the directory. Only if the requestor is the owner do we include the number of sharers. Otherwise, it doesn’t matter at all and we just set the sharers to 0.
- ::
- panic: Invalid transition system.caches.controllers0 time: 5332 addr: 0x4ac0 event: Inv state: SM_AD
First, let’s look at where Inv is triggered. If you get an invalidate… only then. Maybe it’s that we are on the sharer list and shouldn’t be?
We can use protocol trace and grep to find what’s going on.
``` {.sourceCode .sh} build/MSI/gem5.opt –debug-flags=ProtocolTrace configs/learning_gem5/part6/ruby_test.py | grep 0x4ac0
...
4541 0 L1Cache Replacement MI_A>MI_A [0x4ac0, line 0x4ac0]
4542 0 L1Cache PutAck MI_A>I [0x4ac0, line 0x4ac0]
4549 0 Directory MemAck MI_M>I [0x4ac0, line 0x4ac0]
4641 0 Seq Begin > [0x4aec, line 0x4ac0] LD
4652 0 L1Cache Load I>IS_D [0x4ac0, line 0x4ac0]
4657 0 Directory GetS I>S_M [0x4ac0, line 0x4ac0]
4669 0 Directory MemData S_M>S [0x4ac0, line 0x4ac0]
4674 0 Seq Done > [0x4aec, line 0x4ac0] 33 cycles
4674 0 L1Cache DataDirNoAcks IS_D>S [0x4ac0, line 0x4ac0]
5321 0 Seq Begin > [0x4aec, line 0x4ac0] ST
5322 0 L1Cache Store S>SM_AD [0x4ac0, line 0x4ac0]
5327 0 Directory GetM S>M_M [0x4ac0, line 0x4ac0]
Maybe there is a sharer in the sharers list when there shouldn't be? We
can add a defensive assert in clearOwner and setOwner.
``` {.sourceCode .c++}
action(setOwner, "sO", desc="Set the owner") {
assert(getDirectoryEntry(address).Sharers.count() == 0);
peek(request_in, RequestMsg) {
getDirectoryEntry(address).Owner.add(in_msg.Requestor);
}
}
action(clearOwner, "cO", desc="Clear the owner") {
assert(getDirectoryEntry(address).Sharers.count() == 0);
getDirectoryEntry(address).Owner.clear();
}
Now, I get the following error:
panic: Runtime Error at MSI-dir.sm:301: assert failure.
This is in setOwner. Well, actually this is OK since we need to have the sharers still set until we count them to send the ack count to the requestor. Let’s remove that assert and see what happens. Nothing. That didn’t help anything.
When are invalidations sent from the directory? Only on S->M_M. So, here, we need to remove ourselves from the invalidation list. I think we need to keep ourselves in the sharer list since we subtract one when sending the number of acks.
Note: I’m coming back to this a little later. It turns out that both of these asserts are wrong. I found this out when running with more than one CPU below. The sharers are set before clearing the Owner in M->S_D on a GetS.
So, onto the next problem!
panic: Deadlock detected: current_time: 56091 last_progress_time: 6090 difference: 50001 processor: 0
Deadlocks are the worst kind of error. Whatever caused the deadlock is ancient history (i.e., likely happened many cycles earlier), and often very hard to track down.
Looking at the tail of the protocol trace (note: sometimes you must put the protocol trace into a file because it grows very big) I see that there is an address that is trying to be replaced. Let’s start there.
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
56091 0 L1Cache Replacement SM_A>SM_A [0x5ac0, line 0x5ac0]
Before this replacement got stuck I see the following in the protocol trace. Note: this is 50000 cycles in the past!
...
5592 0 L1Cache Store S>SM_AD [0x5ac0, line 0x5ac0]
5597 0 Directory GetM S>M_M [0x5ac0, line 0x5ac0]
...
5641 0 Directory MemData M_M>M [0x5ac0, line 0x5ac0]
...
5646 0 L1Cache DataDirAcks SM_AD>SM_A [0x5ac0, line 0x5ac0]
Ah! This clearly should not be DataDirAcks since we only have a single CPU! So, we seem to not be subtracting properly. Going back to the previous error, I was wrong about needing to keep ourselves in the list. I forgot that we no longer had the -1 thing. So, let’s remove ourselves from the sharing list before sending the invalidations when we originally get the S->M request.
So! With those changes the Ruby tester completes with a single core. Now, to make it harder we need to increase the number of loads we do and then the number of cores.
And, of course, when I increase it to 10,000 loads there is a deadlock. Fun!
What I’m seeing at the end of the protocol trace is the following.
144684 0 L1Cache Replacement MI_A>MI_A [0x5bc0, line 0x5bc0]
...
144685 0 Directory GetM MI_M>MI_M [0x54c0, line 0x54c0]
...
144685 0 L1Cache Replacement MI_A>MI_A [0x5bc0, line 0x5bc0]
...
144686 0 Directory GetM MI_M>MI_M [0x54c0, line 0x54c0]
...
144686 0 L1Cache Replacement MI_A>MI_A [0x5bc0, line 0x5bc0]
...
144687 0 Directory GetM MI_M>MI_M [0x54c0, line 0x54c0]
...
This is repeated for a long time.
It seems that there is a circular dependence or something like that causing this deadlock.
Well, it seems that I was correct. The order of the in_ports really matters! In the directory, I previously had the order: request, response, memory. However, there was a memory packet that was blocked because the request queue was blocked, which caused the circular dependence and the deadlock. The order should be memory, response, and request. I believe the memory/response order doesn’t matter since no responses depend on memory and vice versa.
Now, let’s try with two CPUs. First thing I run into is an assert failure. I’m seeing the first assert in setState fail.
``` {.sourceCode .c++} void setState(Addr addr, State state) { if (directory.isPresent(addr)) { if (state == State:M) { assert(getDirectoryEntry(addr).Owner.count() == 1); assert(getDirectoryEntry(addr).Sharers.count() == 0); } getDirectoryEntry(addr).DirState := state; if (state == State:I) { assert(getDirectoryEntry(addr).Owner.count() == 0); assert(getDirectoryEntry(addr).Sharers.count() == 0); } } }
To track this problem down, let's add a debug statement (DPRINTF) and
run with protocol trace. First I added the following line just before
the assert. Note that you are required to use the RubySlicc debug flag.
 The other options is in setOwner we could have Set the Owner specifically instead of adding it to the NetDest.
Oooo! This is a new error!
panic: Runtime Error at MSI-dir.sm:229: Unexpected message type..
What is this message that fails? Let’s use the RubyNetwork debug flag to try to track down what message is causing this error. A few lines above the error I see the following message whose destination is the directory.
The destination is a NetDest which is a bitvector of MachineIDs. These are split into multiple sections.  It seems that we are setting the requestor wrong when we send the invalidate (Inv) message to the L1 caches from the directory.
Yes. This is the problem. We need to make the requestor the original requestor. This was already correct for the FwdGetS/M, but I missed the invalidate somehow. On to the next error!
panic: Invalid transition
system.caches.controllers0 time: 2287 addr: 0x8c0 event: LastInvAck state: SM_AD
This seems to be that I am not counting the acks correctly. It could also be that the directory is much slower than the other caches at responding since it has to get the data from memory.
If it’s the latter (which I should be sure to verify), what we could do is include an ack requirement for the directory, too. Then, when the directory sends the data (and the owner, too) decrement the needed acks and trigger the event based on the new ack count.
Actually, that first hypothesis was not quite right. I printed out the number of acks whenever we receive an InvAck and what’s happening is that the other cache is responding with an InvAck before the directory has told it how many acks to expect.
So, what we need to do is something like what I was talking about above. First of all, we will need to let the acks drop below 0 and add the total acks to it from the directory message. Then, we are going to have to complicate the logic for triggering last ack, etc.
Ok. So now we’re letting the tbe.Acks drop below 0 and then adding the directory acks whenever they show up.
Next error: This is a tough one. The error is now that the data doesn’t match as it should. Kind of like the deadlock, the data could have been corrupted in the ancient past. I believe the address is the last one in the protocol trace.
- ::
- panic: Action/check failure: proc: 0 address: 19688 data: 0x779e6d0 byte_number: 0 m_value+byte_number: 53 byte: 0 [19688, value: 53, status: Check_Pending, initiating node: 0, store_count: 4]Time: 5843
So, it could be something to do with ack counts, though I don’t think this is the issue. Either way, it’s a good idea to annotate the protocol trace with the ack information. To do this, we can add comments to the transition with APPEND_TRANSITION_COMMENT.
{.sourceCode .c++}
action(decrAcks, "da", desc="Decrement the number of acks") {
assert(is_valid(tbe));
tbe.Acks := tbe.Acks - 1;
APPEND_TRANSITION_COMMENT("Acks: ");
APPEND_TRANSITION_COMMENT(tbe.Acks);
}
5737 1 L1Cache InvAck SM_AD>SM_AD [0x400, line 0x400] Acks: -1
For these data issues, the debug flag RubyNetwork is useful because it prints the value of the data blocks at every point it is in the network. For instance, for the address in question above, it looks like the data block is all 0’s after loading from main-memory. I believe this should have valid data.  After lots of digging and using the MemoryAccess debug flag to see exactly what was being read and written to main memory, I found that in sendDataToMem I was using the request_in. This is right for PutM, but not right for Data. We need to have another action to send data from response queue!
panic: Invalid transition
system.caches.controllers0 time: 44381 addr: 0x7c0 event: Inv state: SM_AD
Invalid transition is my personal favorite kind of SLICC error. For this error, you know exactly what address caused it, and it’s very easy to trace through the protocol trace to find what went wrong. However, in this case, nothing went wrong, I just forgot to put this transition in! Easy fix!


Installation and Invocation¶
Installing with Pip¶
There are few different ways to install EUKulele
, but the easiest is:
pip install EUKulele
There may some Python dependencies that are not immediately downloaded when EUKulele
is pip-installed. If this is the case, the offending dependencies may be installed individually.
The external dependencies can be installed individual, or with conda using:
conda create -n EUKulele
conda activate EUKulele
conda install -c bioconda -c conda-forge blast busco=4.0.6 diamond transdecoder
As the dependencies external to PyPI are:
BLAST
BUSCO
Diamond
TransDecoder (if using metatranscriptome samples and the
--use_transdecoder
flag)
Installing with conda
¶
EUKulele
may also be downloaded as a conda
package, which will eventually become the easiest option, as conda automatically installs all dependencies for the user. The package can currently be downloaded via:
conda install -c akrinos -c bioconda -c conda-forge EUKulele
Eventually, the -c akrinos
designation will be replaced, when EUKulele
becomes a bioconda
package, at which point it may be installed from that channel (and this documentation will be updated).
Cloning the Development Code from GitHub¶
In addition, you can clone EUKulele
from GitHub (the current development version) using:
git clone https://github.com/AlexanderLabWHOI/EUKulele
And then invoke EUKulele
either by executing the script bin/EUKulele
directly, or by installing EUKulele
as a local package, by calling the following from the EUKulele
directory:
python3 -m pip install -e . --user
python setup.py install --user
Again, in this case, external dependencies may be installed via:
conda create -n EUKulele
conda activate EUKulele
conda install -c bioconda -c conda-forge blast busco=4.0.6 diamond transdecoder
Or individually for each software.
Invoking EUKulele
¶
If installed either with pip or conda
, EUKulele
can be invoked via:
EUKulele <arguments>
Where the minimal command would be:
EUKulele --mets_or_mags <choice of data type> --sample_dir <where samples are located>
In which case EUKulele
would be run with mostly parameter defaults and using the MMETSP database, by default.
EUKulele
may also be run as a module within Python. Include the phrase import EUKulele
in the header of a Python file. Then, you may execute EUKulele
using:
EUKulele.eukulele(config=config_file)
in the case that you have a configuration file to specify (replace the config_file
variable with this path), or with:
EUKulele.eukulele(string_arguments=string_of_arguments)
where string_of_arguments
is a string containing the non-default EUKulele options you wish to specify.


AUSTIN POWERS: INTERNATIONAL MAN OF MYSTERY A film review by Andrew Hicks Copyright 1997 Andrew Hicks / Fatboy Productions
(1997) ** (out of four)
I'd like to meet the executive who green-lighted this project and ask him that crucial word -- why? Mike Myers hasn't starred in a movie since 1993's SO I MARRIED AN AX-MURDERER, to which most people responded "So what?" Now he comes up with the brilliant idea to do a James Bond parody. Gee, and it's been almost a year since the last one, SPY HARD. That's two immediate strikes against AUSTIN POWERS and, enough lame jokes ensue that, in most ways, it's an even three strikes.
Still, that immature part of me that used to love Myers on "Saturday Night Live" back in the early '90s has a hard time stifling laughter every once in awhile. Yes, this movie could have written itself, given its unoriginal premise and mediocre star. We've got the requisite scene in which Myers tries to play a compact disc on a record turntable and the one where he sees a masculine-looking woman and tries to pull her "wig" off to reveal she's a man, but it's her real hair. Stop my sides from splitting. He even recycles the "Wayne's World" bit where he turns a couch into a canoe, an elevator and an escalator. Oh yeah, Garth finally got pubes...
The plot is as follows -- secret agent Austin Powers (Myers, naturally) was cryogenically frozen in 1967, when his adversary Dr. Evil (also played by Myers) also froze himself. Now it's 1997 and they're both thawed out. The world has advanced and left them in the swinging '60s, when a million dollars seemed like an exorbitant sum and free love was, well, free. However will they survive now that the world's gone on without them? It's THE BRADY BUNCH MOVIE all over again. And, come on, even the James Bond movie GOLDENEYE had fun with the notion of the Bond ideal being outdated.
Let's focus on Dr. Evil for a second. Myers experimented with multiple roles back in AX-MURDERER, and he's still no Peter Sellers. Here, he latches onto the Donald Pleasance version of Blofeld, complete with scar and cat, albeit a sickening-loooking hairless cat. There a few amusing moments when he tries to resume his '60s plans for world domination by cutting a hole in the ozone layer and again when he meets his angst-ridden teenage son, who of course spouts '90s cliches about parental relationships. In the end, Evil decides to go the age-old Bond route -- destruction via nuclear weapons.
There's a supporting cast too. Evil henchpeople like Random Task (the Odd Job clone), Alotta Fagina and #2 (Robert Wagner -- what's he doing in this movie?!) mingle with an unexplained cameo by Tom Arnold. Hugh Grant's prettier half, Elizabeth Hurley is the archetypal Bond girl, an agent Powers works with and tries all his worn '60s come-on techniques on. All of this is auto-pilot humor that I sincerely hope Myers didn't spend more than a few weeks writing.
Like any Myers movie, there are some funny moments mixed in with the pathetic ones. The entire subplot with with Dr. Evil and his son was inspired, from Evil proving he's hip by dancing the Macarena to sitting through group therapy with his son. Then there's probably the only original thing in the movie, when Powers is nude and a series of strategically-placed objects keep us from glimpsing his bits and pieces. When you go into a Mike Myers movie, the best you can hope for is a few scattered laughs. AUSTIN POWERS lives up to those lowered expectations.
--
Visit the Movie Critic at LARGE homepage at http://www.missouri.edu/~c667778/movies.html
Serving America For Nearly 1/25th of a Century!
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Help us to build the Hospital (Luther Hospital) which will carter for both physical and spiritial needs of Tanzania and neighbour countries.
You welcome to volunteer for whatever can be touched to help us stand improve building thy kingdom of God cometh through building Luther Medical Center.
2 Corinthians 9:6-8 Whoever sows sparingly will also reap sparingly, and whoever sows generously will also reap generously. Each of you should give what you have decided in your heart to give, not reluctantly or under compulsion, for God loves a cheerful giver.
Help us Build The Body of Christ by happily Giving your Offering and may the Loard God bless you abundantly.
1 JOHN 3:16–18, GIVING LIKE CHRIST By this we know love, that he laid down his life for us, and we ought to lay down our lives for the brothers. But if anyone has the world’s goods and sees his brother in need, yet closes his heart against him, how does God’s love abide in him? Little children, let us not love in word or talk but in deed and in truth.
JOHN 3:16, LOVE GIVES. For God so loved the world, that he gave his only Son, that whoever believes in him should not perish but have eternal life..
1 JOHN 2:5–6 By this we may know that we are in him: whoever says he abides in him ought to walk in the same way in which he walked.
ACTS 20:32–35 And now I commit you to God and to the message of His grace, which is able to build you up and to give you an inheritance among all who are sanctified. I have not coveted anyone’s silver or gold or clothing.
Pastors
Rev.Willbroad Mastai, KKKT Kimara Korogwe.“Everyone to whom much was given, of him much will be required, and from him to whom they entrusted much, they will demand the more LUKE 12:48.”
Pastor, Joseph Aggrey Maseghe.“So do not fear, for I am with you; do not be dismayed, for I am your God.
Mercy Ndosi Shoo,Elder Diaspora.“ Commit your way to the LORD; trust in him and he will do this:” psalm 37:5
Shose Katende,Elder Diaspora.“And he gave the apostles, the prophets, the evangelists, the shepherds and teachers, to equip the saints for the work of ministry, ”Ephesian 4:11
1 Chronicles 17:12 He shall build for Me a house, and I will establish his throne forever .
 "And the people all tried to touch him, because power was coming from him and healing them all." "'But I will restore you to health and heal your wounds,' declares the Lord.
James 1:27 says, “Religion that is pure and undefiled before God, the Father, is this: to visit orphans and widows in their affliction, and to keep oneself unstained from the world.
Proverbs 22:6 Train up a child in the way he should go: and when he is old, he will not depart from it..


FuryDevs is a team of Developers, Designers and Managers. Everyone among us is motivated to deliver best products to our customers. We believe that our customers experience with us is our only duty that has to done accordingly. We continuously strive to maintain the good relation with our customers.
We know that we are in a field that helps our customers business interms of popularity, brand value and ofcourse, more customers. This gives us the motivation to work more with our customers to meet and fulfill your expectations. Online presence for your business is most essential in today's era of Technology. Making your business online will take you to the more and real customers with no limits of Distance/Availability.
Chief Executive Officer
Chief Technology Officer
Chief Financial Officer
Chief Operating Officer


The life of an algorithmic machine
In the broad economic context
It brings much wind
I always did
Always will
The nature of my brain
Changes
Variations
Unknowns
In the road of my life.
In all of this,
In all the things that came
In all the things that come
In all the things that will come,
My Sunshine
Is the immutable
Indisputable
Eternal
Infinite
Blessed
Divine
Meaning
Certainty
Force in my life
Pushing my heart forward
Closer
And closer.
I don't know what I will want
I don't know how I will work
I don't know what I will do
But I know
Truer than anything in my heart
That I want to make us
Full, free, genuine, loving halves
Focused in the truthfulness of life
That I want to make her
The happiest
The brightest
Biggest smiling
Star in the entire universe
And as my compass
As partners
As lovers
As halves
I will make her
My future
My road
My treasure
My key.