Posts Tagged ‘intel’

A feature-detection example using the Intel® Threading Building Blocks flow graph

The Intel® Threading Building Blocks ( Intel® TBB )  flow graph is fully supported in Intel® TBB 4.0.  If you are unfamiliar with the flow graph, you can read an introduction here . Figure 1 below shows a flow graph that implements a simple feature detection application. A number of images will enter the graph and two alternative feature detection algorithms will be applied to each one. If either algorithm detects a feature of interest, the image will be stored for later inspection. In this article, I’ll describe each node used in this graph, and then provide and described a complete working implementation. Figure 1: The Intel® TBB flow graph for the feature-detection example. In the figure, there are four different type of nodes used to construct the application: a source_node , a queue_node , two join_node s, and several function_node s. Before I provide a sample implementation, I’ll provide a brief overview of each node. The first type of node is a source_node , which is shown pictorially using the symbol below. This type of node has no predecessors, and is used to generate messages that are injected into the graph. It executes a user functor (or lambda expression) to generate its output. The unfilled circle on its right side indicates that it buffers its output and that this buffer can be reserved. The source_node buffers a single item. When a buffer is reserved, a value is held for the caller until the caller either consumes or releases the value. A source_node will only invoke the user functor when there is nothing currently buffered in its single item output buffer. The second type of node is a queue_node , which is show using the figure below. A queue_node is an unbounded first-in first-out buffer. Like the source_node , its output is reservable. The third type of node, of which there are two variants used in the example, is the join_node . A join_node has multiple input ports and generates a single output tuple that contains a value received at each port. A join_node can use different policies at its input ports: queueing , reserving or tag_matching . A queueing join_node , greedily consumes all messages as they arrive and generates an output whenever it has at least 1 item at each input queue. A reserving join_node only attempts to generate a tuple when it can successfully reserve an item at each input port. If it cannot successfully reserve all inputs, it releases all of its reservations and will only try again when it receives a message from the port or ports it was previously unable to reserve. Lastly, a tag_matching join_node uses hash tables to buffer messages in its input ports. When it has received messages at each port that have matching keys, it creates an output tuple with these messages. Shown below are the symbol for the reserving and tag_matching join_node s used in Figure 1. The final node type used in this example is a function_node ; it uses the symbol shown below. A function_node executes a user-provided functor or lambda expression on incoming messages, passing the return value to its successors. A function_node can be constructed with a limited or unlimited allowable concurrency level. A function_node with unlimited concurrency creates a task to apply its functor to each message as they arrive. If a function_node has limited concurrency, it will create tasks only up to its allowed concurrency level, buffering messages at its input as necessary so that they are not dropped. To save on space, I’m going to fake the image processing parts of this example. In particular, each image will simply be an array of characters. An image that contains the character ‘A’ has a feature recognizable by algorithm A, and an image that contains the character ‘B’ has a feature recognizable by algorithm B. So in the post, I will provide the complete code to construct and execute a flow graph that has the structure shown in Figure 1, but I’ll replace the actual computations with trivial ones. Below is the declaration of struct image , as well as the trivial implementations that can be used as the bodies of the function nodes. The function get_next_image will be used by the source_node to generate images for processing. You might note that in get_next_image , every 11th image will have a feature detectable by algorithm A and every 13th image will contain a feature detectable by algorithm B. The function preprocess_image adds a simple offset to each character, and detect_with_A and detect_with_B do the trivial search for the characters ‘A’ and ‘B’, respectively. #include #include const int num_image_buffers = 100; int image_size = 10000000; struct image {    const int N;    char *data;    image();    image( int image_number, bool a, bool b ); }; image::image() : N(image_size) {    data = new char[N]; } image::image( int image_number, bool a, bool b ) : N(image_size) {     data = new char[N];     memset( data, ‘’, N );     data[0] = (char)image_number – 32;     if ( a ) data[N-2] = ‘A’;     if ( b ) data[N-1] = ‘B’; } int img_number = 0; int num_images = 64; const int a_frequency = 11; const int b_frequency = 13; image *get_next_image() {     bool a = false, b = false;     if ( img_number < num_images ) {         if ( img_number%a_frequency == 0 ) a = true;         if ( img_number%b_frequency == 0 ) b = true;         return new image( img_number++, a, b );     } else {        return false;     } } void preprocess_image( image *input_image, image *output_image ) {     for ( int i = 0; i < input_image-> N; ++i ) {         output_image-> data[i] = input_image-> data[i] + 32;     } } bool detect_with_A( image *input_image ) {     for ( int i = 0; i < input_image-> N; ++i ) {         if ( input_image-> data[i] == ‘a’ )             return true;     }     return false; } bool detect_with_B( image *input_image ) {     for ( int i = 0; i < input_image-> N; ++i ) {         if ( input_image-> data[i] == ‘b’ )             return true;     }     return false; } void output_image( image *input_image, bool found_a, bool found_b ) {     bool a = false, b = false;     int a_i = -1, b_i = -1;     for ( int i = 0; i < input_image-> N; ++i ) {         if ( input_image-> data[i] == ‘a’ ) { a = true; a_i = i; }         if ( input_image-> data[i] == ‘b’ ) { b = true; b_i = i; }     }     printf(“Detected feature (a,b)=(%d,%d)=(%d,%d) at (%d,%d) for image %p:%dn”, a, b, found_a, found_b, a_i, b_i, input_image, input_image-> data[0]); } The code to implement the flow graph itself is shown in function main below. I will interject text in the middle of the listing of main to describe the use of the flow graph components. If you want to build this example, you can just cut and paste the code snippets above and below linearly into a single file. int num_graph_buffers = 8; #include “tbb/flow_graph.h” using namespace tbb; using namespace tbb::flow; int main() { First, a graph g is created. All of the nodes will belong to this single graph. A few typedefs are provided to make it easier to refer to the outputs of the join nodes:     graph g;     typedef std::tuple< image *, image * > resource_tuple;     typedef std::pair< image *, bool > detection_pair;     typedef std::tuple< detection_pair, detection_pair > detection_tuple; Next, the queue_node that holds the images buffers is created, along with the two join nodes. Again, note that the resource_join is using the reserving policy, while detection_join uses the tag_matching policy. To use tag_matching , the user must provide functors that can extract the tag from the item; these appear as the additional arguments to the constructor.     queue_node< image * > buffers( g );     join_node< resource_tuple, reserving > resource_join( g );     join_node< detection_tuple, tag_matching > detection_join( g, [](const detection_pair &p) -> size_t { return (size_t)p.first; },             [](const detection_pair &p) -> size_t { return (size_t)p.first; }  ); Next, the nodes that execute the user’s code are created, including the source_node and the four function_nodes . The user’s code is passed to each node using a C++ lambda expression ( a function object could also be used ). For the most part, each lambda expression is a bit of wrapper code that calls the functions that were described earlier, obtaining inputs and creating outputs as necessary. The make_edge calls wire together the nodes as shown in Figure 1.     source_node< image * > src( g,                                 []( image* &next_image ) -> bool {                                     next_image = get_next_image();                                     if ( next_image ) return true;                                     else return false;                                 }                               );     make_edge(src, input_port (resource_join) );     make_edge(buffers, input_port (resource_join) );     function_node< resource_tuple, image * >         preprocess_function( g, unlimited,                              []( const resource_tuple &in ) -> image * {                                  image *input_image = std::get (in);                                  image *output_image = std::get (in);                                  preprocess_image( input_image, output_image );                                  delete input_image;                                  return output_image;                              }                            );     make_edge(resource_join, preprocess_function );     function_node< image *, detection_pair >         detect_A( g, unlimited,                  []( image *input_image ) -> detection_pair {                     bool r = detect_with_A( input_image );                     return std::make_pair( input_image, r );                  }                );     function_node< image *, detection_pair >         detect_B( g, unlimited,                  []( image *input_image ) -> detection_pair {                     bool r = detect_with_B( input_image );                     return std::make_pair( input_image, r );                  }                );     make_edge(preprocess_function, detect_A );     make_edge(detect_A, input_port (detection_join) );     make_edge(preprocess_function, detect_B );     make_edge(detect_B, input_port (detection_join) );     function_node< detection_tuple, image * >         decide( g, serial,                  []( const detection_tuple &t ) -> image * {                      const detection_pair &a = std::get (t);                      const detection_pair &b = std::get (t);                      image *img = a.first;                      if ( a.second || b.second ) {                          output_image( img, a.second, b.second );                      }                      return img;                  }                );     make_edge(detection_join, decide);     make_edge(decide, buffers); Because of the reserving join node at the front of the graph, the graph will remain idle until there are image buffers available in the buffers queue. The for-loop below allocates and puts buffers into the queue. After the loop, the call to g.wait_for_all() will block until the graph again becomes idle when all images are processed.     // Put image buffers into the buffer queue     for ( int i = 0; i < num_graph_buffers; ++i ) {         image *img = new image;         buffers.try_put( img );     }     g.wait_for_all(); When the graph is idle, all of the buffers will again be in the buffers queue. The queue_node therefore needs to be drained and the buffers deallocated.:     for ( int i = 0; i < num_graph_buffers; ++i ) {         image *img = NULL;         if ( !buffers.try_get(img) )             printf(“ERROR: lost a buffern”);         else             delete img;     } return 0; } I hope that this feature-detection example demonstrates how a reasonably complex flow graph that passes messages between nodes can be implemented. To learn more about the new features in Intel® Threading Building Blocks 4.0, visit http://www.threadingbuildingblocks.org  or to learn more about the Intel® TBB flow graph, check-out the other blog articles at http://software.intel.com/en-us/blogs/tag/flow_graph/ .

Implementing a wave-front computation using the Intel® Threading Building Blocks flow graph

The Intel® Threading Building Blocks ( Intel® TBB )  flow graph is fully supported in Intel® TBB 4.0.  If you are unfamiliar with the flow graph, you can read an introduction here . One node type available for use with the flow graph is continue_node .  This node type is designed for implementing dependency graphs, where nodes wait for their predecessors to complete before beginning their own work.   A continue_node does not receive data messages from its predecessors, but instead counts the number of continue_msg signals that it receives.  Once it receives P messages, one for each predecessor, it executes its body which generates an output message of type T .  Often, the output type is also a continue_msg but it need not be.  Pictorially, we draw a continue_node as below:   This symbol tries to convey important properties about a continue_node .  The input arc has lines above it to indicate that it counts incoming messages.  The interior of the circle contains f() to indicate that the body is a functor that is passed no argument. Figure 1 shows an approach to implementing a wave front computation using a set of continue_node objects.  In this example, each computation must wait for the computation above it and the computation to its left to complete before it can start executing.  Most nodes have two predecessors and therefore will not start executing until they receive two continue_msg messages.  Nodes on the top and left edges have only a single predecessor and therefore wait for only a single message to arrive. Figure 1: Using an Intel® Threading Building Blocks flow graph to express a wave-front calculation I’ll now provide the complete code necessary to implement an example that performs such a computation using an Intel® TBB flow graph. In this example, the computation at each node will update a block of a 2 dimensional matrix. If the values held by an element’s left and upper neighbors are equal, then the element’s value will be set to be 2 times that value. Otherwise, the element’s value will be set to be the maximum of the two values. The top-left element is initialize with a value of 1. So for a 5×5 matrix, the results would be: 1 1 1 1 1 1 2 2 2 2 1 2 4 4 4 1 2 4 8 8 1 2 4 8 16 The code below includes the necessary headers, defines some parameters, and defines the function calc that performs the calculation on each matrix element. The constants M and N define the size of the matrix. The dimension of the blocks computed in each node is given by the blocksize, B , and the number of blocks in each dimenstion is computed and stored in MB and NB . The 2-D matrix, values , is where the results will be stored. #include // for std::max #include #include “tbb/flow_graph.h” using namespace tbb; using namespace tbb::flow; int M=1000, N=1000; int B = 100; int MB = (M/B) + (M%B> 0); int NB = (M/B) + (M%B> 0); double **value; inline double calc( double v0, double v1 ) {   if ( v0 == v1 )     return 2*v0;   else     return std::max(v0,v1); } The code below builds the flow graph that will apply the function calc to the matrix blocks, while respecting the dependencies shown in Figure 1. The 2-D array, node , is used to hold pointers to the continue_node objects. In BuildGraph , the doubly-nested for loop allocates the continue_node objects. Each node is constructed with a reference to the graph object g and lambda expression that applies calc to its corresponding block of elements. After each node is created, edges are made from it to its successors in the graph, setting up the required dependencies. Note that the loop indices move from the bottom right of Figure 1 to the top left, so each node’s successors are allocated before it. continue_node ***node; void BuildGraph( graph &g ) {   value[M-1][N-1] = 0;   for( int i=MB; –i> =0; )     for( int j=NB; –j> =0; ) {       node[i][j] =         new continue_node ( g,                          [=]( const continue_msg& ) {                            int start_i = i*B;                            int end_i = (i*B+B > M) ? M : i*B+B;                            int start_j = j*B;                            int end_j = (j*B+B > N) ? N : j*B+B;                            for ( int ii = start_i; ii < end_i; ++ii ) {                              for ( int jj = start_j; jj < end_j; ++jj ) {                                double v0 = ii == 0 ? 0 : value[ii-1][jj];                                double v1 = jj == 0 ? 0 : value[ii][jj-1];                                value[ii][jj] = ii==0 && jj==0 ? 1 : calc(v0,v1);                               }                            }                          } );       if ( i + 1 < MB ) make_edge( *node[i][j], *node[i+1][j] );       if ( j + 1 < NB ) make_edge( *node[i][j], *node[i][j+1] );     } } The function EvaluateGraph executes the flow graph. It does this by putting a continue_msg to the top-left element, and then waiting for the activity in the graph to stop. When the call to g.wait_for_all() returns, all of the nodes have been evaluated and the final result produced. double EvaluateGraph( graph &g ) {   node[0][0]-> try_put(continue_msg());   g.wait_for_all();   return value[M-1][N-1]; } Since we create a matrix of continue_node objects, we also have to delete them: void CleanupGraph() {   for( int i=0; i

Flow Graph Feature in TBB 4.0 with Michael Voss – Parallel Programming Talk #121

It’s time for Parallel Programming Talk This is show  #121– Clay and I will be talking with Intel Software Architect Mike Voss But first the news: The News There is now an open source implementation of Cilk(TM) Plus based on gcc 4.7. Can you explain why this is good news?  Information on how to contribute is at: http://software.intel.com/en-us/articles/contribute-to-intel-cilk-plus/ Source is at: http://software.intel.com/en-us/articles/download-intel-cilk-plus-source/  I’ll also include links to a couple of hot blogs on the subject – both are drawing high site traffic!   http://software.intel.com/en-us/blogs/2011/08/09/parallelism-as-a-first-class-citizen-in-c-and-c-the-time-has-come/   http://software.intel.com/en-us/blogs/2009/08/03/hello-lambdas-c-0x-a-quick-guide-to-lambdas-in-c/  The Intel Developer Forum is less than a month away– September 13-15 at the Moscone Center in San Francisco http://www.intel.com/idf/   Clay and I have some things planned – we’ll  both be interviewing folks – a few Parallel Programming Talk shows will be done and we will have them available for viewing shortly thereafter.  ISN is doing something new at IDF – we are sponsoring a lab, being run by our newest Community Black Belt Developer Noah Clemons.                               Faces of Parallelism Open Lab: Parallel Models for Multi/Many Core  Join this open lab whenever you want. It will be open from Wed, September 14 – 1:05 – 5:15pm. All levels of experience are welcome. You will experience Intel® Software Programming  Tools and the wide variety of programming models supported. This hands-on-lab provides attendees the opportunity to see how the latest Intel® silicon features are unlocked via Intel’s optimized Software Tools product line.  You will have the opportunity to provide feedback on your experience, by blog or video (we will provide everything needed)and those who choose to do so will be entered into a contest. Four prizes will be awarded. Don’t miss this one.   Read more about the lab, contest, etc. Session ID: SFTL004   Threading Challenge – Intel® Threading Challenge 2011 Phase 1 Problem 2 Apprentice and Master Winners Announced.   Master Level Winner – Akshay Singh, India, Apprentice Level – Rick LaMont, USA    OOPSLA (Now a part of SPLASH – Systems, Programming, Languages and Applications: Software for Humanity .) October 22-27 in Portland  - a panel discussion on “Multicore, Manycore, and Cloud Computing: Is a new programming language paradigm required? ” http://splashcon.org/2011/program/panels/229-multicore-manycore-and-cloud-computing-is-a-new-programming-language-paradigm-required   The Intel Academic Community will soon be hosting new rounds of microgrant funding to create parallel programming training material . The first round will be focused on Data Structures. If you’re in academia and have some ideas about teaching parallelism, go to the IAC microgrant site for more information. I’ll have the URL in the show notes or you can find it from the academic community homepage. If you have comments, questions, suggestions for guests or show topics, news to share that you think would be of interest, we’d love to hear from you. Clay, where can they send those ideas? K: Now for something we know you’ll really like – our guest. Questions asked during the show: Welcome to Parallel Programming Talk – Michael. Before we get into the TBB Flow Graph discussion, could you tell us a little about yourself – background, what do you do at Intel C: In case our viewers don’t know, what is TBB and why are Flow Graphs important – how does this compare with the TBB Graph API?                M:Used to be called “the TBB graph API” is now the “TBB flow graph”. K: What is this used for?                M:The TBB flow graph can express acyclic dependency graphs, as well as acyclic and cyclic messaging graphs. C: How long has this feature existed? Who has used it? What kind of response have you received?               M: Has been a Community Preview feature since Intel® TBB 3.0 U5 (Dec 2010) and now is a full feature in TBB 4.0 (? September 2011 ?) Since Dec 2010, evaluated by customers across media, gaming,       financial services and technical computing K: What were customers doing before the flow graph?               M: Forced apps in to the linear Intel® TBB pipeline, Built their own abstractions over Intel® TBB tasks, Or built their own thread-based graph libraries C: What can flow graphs be used for? Do you have any examples you can share?               M:A flow graph is made of a graph object, nodes and edges.  The nodes may execute user code, buffer or direct messages.  The graph object is the parent of all of the tasks executing in the graph.  The edges make the connections between nodes explicit.  Watch Video to see the examples              M:Some apps that fit a flow graph can already be expressed using the TBB pipeline or a graphs of tasks If an app can be fit into a pipeline the flow graph version and pipeline version usually have similar performance The pipeline version will tend to require less code, since the edges are implicit and there is no need for join or split nodes If an app can be fit into a graph of tasks the flow graph version and task graph version usually have similar performance the flow graph version will be simpler to implement and require less code Many apps are impractical to express as a pipeline or graph of tasks, but can be handled by the TBB flow graph C:Can viewers try this out for themselves? K: Michael, thanks for being our guest today – how can our community members  learn more?                     M: Lots of blogs will be available soon at http://software.intel.com/en-us/blogs/tag/flow_graph If you have comments, questions, suggestions for guests or show, send those ideas     To   parallelprogrammingtalk@intel.com Today’s show was posted September 9. There will not be a new show on September 27.  We will have a number of recordings and special episodes available soon after. Weekly Tuesday morning streamed shows will resume taping on September 20 with a release on the following Friday. Watch the calendar on the Parallel Programming Home page for the latest info on Parallel Programming Talk and additional Community Events. A wise old programmer once told me – a trouble parallelized is a trouble halved

So Glad IDF Doesn’t Start ‘Til Tuesday

As I sit at home on the Saturday night before the Intel Developer Forum 2011 I am still checking off lists – what to pack (a major list), making sure I’ve got complete notes for the 11 Videos that Dr. Clay Breshears and I will make for the community (of course our fine videographer Jerry Makare will do the actual filming and editing). We will be interviewing the makers of several new software applications that have come about because of Intel Architechture. Names to look for include Pervasive’s Data Rush and Critical Blue’s Prism. (I have always thought that the namers of software are an uber-creative bunch.) We will be talking with many ISN Parallel Programming Black Belt Developers – those are the cream of the community crop as it were – real coding gurus who not only know their stuff – they routinely reach out and help developers who don’t have quite the experience that they do. This year there are ten Parallel Programming Community Black Belts attending – keep checking back for these videos that will be appearing on the Community in the days following IDF. The charter members of this elite group are Igor Levicki and Jim Dempsey, from Serbia and good old Oshkosh Wisconsin respectively. Jim and Igor, don’t forget your sunglasses (and a jacket). Other countries represented in our BB group include Argentina and Belgium. We are having our annual Black Belt meetup on Wednesday with a nice dinner planned. Intel Parallelism Guru James Reinders will be speaking at the dinner – always good to hear from James about what is on the horizon for parallelism, at Intel and around our industry. This year’s Forum promises to be another whirlwind of activity – Keynotes from Paul Otellini and Justin Ratner will be high points for sure. Clay and I will also be supporting Intel Technical Consulting Engineer (and newest Community Black Belt Developers) Noah Clemons as he presents a truly unique hands-on lab. Called Intel® Faces of Parallelism Lab: Parallel Models for Multi/Many Core” (SFTL004) On Wednesday, Sept. 14 join anytime from 1-5pm to see how the latest Intel® silicon features are unlocked via Intel’s optimized Software Tools. You might win a Sony Internet TV! Read Clay’s latest blog for more details. Well, lots to do before leaving Monday afternoon – thank goodness it’s only a 30-minute drive for me and I’ll have time to catch my breath before my first appointment with the whirlwind on Tuesday morning. If you’re there come and find me along with other ISN folks. We want to meet you and show you what is new.

Visit the Intel AppUp developer program at IDF 2011!

Developers, make sure to swing by and visit the Intel AppUp developer program at the Intel Developer Forum this week! We’re located in the IDF Technology Showcase in the Intel Software Community and will be showing off our developer program and Intel AppUp center apps running on a variety of brand new hardware in different form factors. We also have a panel session on Thursday, September 15 at 1:05pm (room 2009) led by our Intel AppUp Community Manager, Bob Duffy, on “Apps Across the Continuum: Developing Apps for Multiple Devices”. read more

AppUp powered store, pre-installed on ASUS – Video

The Intel AppUp SM developer program slogan is, “multiple devices, multiple OS’, multiple app stores; one program”. Along those lines we’ve been working to get AppUp as a framework for retailers, service providers and device manufacturers. Currently there around 20 AppUp powered stores and AppUp supports Windows and MeeGo devices. However, we, along with our developers, have been anxiously waiting for AppUp to be preinstalled and shipping on a device from an OEM. Today we see that is the case in this unboxing video from Johannes of NewGadgetsDE . The video takes you thru this sleek new netbook, and looks at the MeeGo OS that’s been customized by ASUS. At around minute 6:44 you can see the ASUS app store, and as it launches its is unmistakably AppUp. So if you’re wanting to develop an app for MeeGo but are waiting until AppUp ships on a device in market, looks like we’re ready for ya :-) read more

French developer Corentin Chary gives Intel AppUpSM developer challenge a dose of culture with Lugdulo’V

Today we announced Lugdulo’V as the winning app of our first country-specific category for the Intel AppUpSM developer challenge: Best Custom App for France. To celebrate developer Corentin Chary’s exciting $20,000 USD win, along with our first region-specific category, I’m sharing a deeper look into Chary’s winning app. Lugdulo’V is a personal favorite of mine. read more

Register for Intel(R) Technical Presentation "Using Intel(R) Inspector XE 2011 with Fortran Applications" by Jackson Marusarz (Technical…

Jackson Marusarz, Technical Consulting Engineer, will be presenting on Aug 17th at 9am PDT on the following topic: Using Intel(R) Inspector XE 2011 with Fortran Applications Please register for this presentation using the following link: https://www1.gotomeeting.com/register/174976360 Here is a short abstract of the presentation: This technical presentation will present an overview of the powerful correctness and security checking features of Intel® Inspector XE. There will be a focus on using Intel Inspector XE on Fortran applications.  The presentation will include example problems detected by the memory, threading, and static security analysis tools as well as some possible solutions. Here is a short bio of the presenter:  Jackson Marusarz is a consulting engineer with Intel’s Developer Products Division.  His areas of expertise include parallel programming and performance tuning for both serial and multi-threaded applications. Please register for the presentation now and attend it on August 17th at 9am PDT. You can ask Jackson questions during the second half of the presentation.

GDC 2011: Levent Akyil video chats about Sandy Bridge, AVX and Intel VTune Amplifier 2011 XE

Do you remember?! Levent Akyil held his tech session live at Game Developers Conference 2011 this morning and talked about the architectural improvements of Sandy Bridge , why developers should look closer at AVX and which hotspots and traps you as a developer can tap in when parallelizing new or existing code – whether you are programming games, audio tools, etc. Right after his session I had the chance to have a chat with Levent about his lecture and I wanted to know more about the following topics: What do software developers need to know about Sandy Bridge and its requirements? What’s the idea behind AVX? Why should software developers use Intel VTune Amplifier 2011 XE ? Ok, click the picture, start the show and listen to his replies!

GDC 2011: How Havok’s tools work and what you can do with them

As you might remember we have interviewed Havok’s Head of Product Management, Andrew Bowell who told us a lot about Havok as a company, about GDC Europe, about their partnership with Intel and many things more. A few hours later I had the chance to have a video chat with Steve Ewart who is Sales Engineer at Havok and who knows a lot about all the tools and features regarding their compelling rendering and texturing solutions. Off we went with our camera, put it in front of one of their demo computers and let Steve show us the nice things you can do with Havok’s tools and technologies like Cloth, Distruction and other funny things. Come and learn all about animation and simulation, rendering and texturing. Have fun with this very interesting 6:30 min video clip! BTW: If you want to know more about Havok’s tools just visit this very informative web page .