00001 //******************************************************************************** 00002 // Copyright 2007-2010 Intel Corporation All Rights Reserved. ** 00003 // ** 00004 // The source code contained or described herein and all documents related to ** 00005 // the source code ("Material") are owned by Intel Corporation or its suppliers ** 00006 // or licensors. Title to the Material remains with Intel Corporation or its ** 00007 // suppliers and licensors. The Material contains trade secrets and proprietary ** 00008 // and confidential information of Intel or its suppliers and licensors. The ** 00009 // Material is protected by worldwide copyright and trade secret laws and ** 00010 // treaty provisions. No part of the Material may be used, copied, reproduced, ** 00011 // modified, published, uploaded, posted, transmitted, distributed, or ** 00012 // disclosed in any way without Intel's prior express written permission. ** 00013 // ** 00014 // No license under any patent, copyright, trade secret or other intellectual ** 00015 // property right is granted to or conferred upon you by disclosure or delivery ** 00016 // of the Materials, either expressly, by implication, inducement, estoppel or ** 00017 // otherwise. Any license under such intellectual property rights must be ** 00018 // express and approved by Intel in writing. ** 00019 //******************************************************************************** 00020 00021 // =============================================================================== 00022 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00023 // 00024 // INCLUDE THIS FILE ONLY TO MAKE YOUR PROGRAM READY FOR DISTRIBUTED CnC 00025 // 00026 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00027 // =============================================================================== 00028 00029 #ifndef __DIST_CNC__H_ 00030 #define __DIST_CNC__H_ 00031 00032 /// \page distcnc CnC for distributed memory (distCnC) 00033 /// 00034 /// In principle, every clean CnC program should run with distCnC. 00035 /// Most of the mechanics of data distribution etc. is handled inside 00036 /// the runtime and the programmer does not need to bother about the 00037 /// gory details. Of course, there are a few minor changes needed to 00038 /// make a program distCnC-ready, but once that's done, it will run on 00039 /// distributed CnC as well as on "normal" CnC (decided at runtime). 00040 /// 00041 /// \section dc_comm Inter-process communication 00042 /// Conceptually, distCnC allows data and computation distribution 00043 /// across any kind of network; but currently only a socket-based 00044 /// communication model is provided. Support for KNF or MPI might 00045 /// follow. 00046 /// 00047 /// \section dc_link Linking for distCnC 00048 /// distCnC is part of the "normal" CnC distribution, e.g. it comes 00049 /// with the necessary communication libraries (cnc_socket). The 00050 /// communication library is loaded on demand at runtime, hence you do 00051 /// not need to link against extra libraries to create distCnC-ready 00052 /// application. Just link your binaries like a "tradiditional" CnC 00053 /// application (explained in the CnC User Guide, which can be found 00054 /// in the doc directory). 00055 /// 00056 /// \section dc_prog Making your program distCnC-ready 00057 /// As a distributed version of a CnC program needs to do things which 00058 /// are not required in a shared memory version, the extra code for 00059 /// distCnC is hidden from "normal" CnC headers. To include the 00060 /// features required for a distributed version you need to 00061 /// \code #include <cnc/dist_cnc.h> \endcode 00062 /// instead of \code <cnc/cnc.h> \endcode . 00063 /// If you want to be able to create optimized binaries for shared 00064 /// memory and distributed memory from the same source, you might 00065 /// consider protecting distCnC specifics like this: 00066 /// @code 00067 /// #ifdef _DIST_ 00068 /// # include <cnc/dist_cnc.h> 00069 /// #else 00070 /// # include <cnc/cnc.h> 00071 /// #endif 00072 /// @endcode 00073 /// 00074 /// In "main", initialize an object CnC::dist_cnc_init< list-of-contexts > 00075 /// before anything else; parameters should be all context-types ever 00076 /// used in the program: 00077 /// @code 00078 /// #ifdef _DIST_ 00079 /// CnC::dist_cnc_init< my_context_type_1 /*, my_context_type_2, ... */ > _dinit; 00080 /// #endif 00081 /// @endcode 00082 /// 00083 /// If and only if your items and/or tags are non-standard data types, 00084 /// the compiler will notify you about the need for serialization 00085 /// capability. Serialization of structs/classes without pointers or 00086 /// virtual functions can easily be enabled using 00087 /// CNC_BITWISE_SERIALIZABLE( type ); others need a "serialize" 00088 /// method or function. See \ref serialization for more details. 00089 /// 00090 /// Step instances are distributed across clients and the host. By 00091 /// default, they are distributed in a round-robin fashion. Note that 00092 /// every process can put tags (and so prescribe new step instances). 00093 /// The round-robin distribution decision is made locally on each 00094 /// process (not globally). 00095 /// 00096 /// If the same tag is put multiple times, it might be scheduled for 00097 /// execution on different processes and the preserveTags attribute of 00098 /// tag_collections will then not have the desired effect. 00099 /// 00100 /// To potentially get around this problem, you can provide a tuner when 00101 /// prescribing steps with a CnC::tag_collection. The tuner should be 00102 /// derived from CnC::default_tuner and provide a method called 00103 /// "pass_on", which takes the tag of the step and the context as 00104 /// arguments and has to return the process number to run the step 00105 /// on. To avoid the aforementioned problem, you simply need to make 00106 /// sure that the return value is independent of the process it is 00107 /// executed on. The pass_on mechanism can be used to provide any 00108 /// distribution strategy which can be computed locally. 00109 /// 00110 /// @code 00111 /// struct my_tuner : public CnC::default_tuner< tag_type, context_type > 00112 /// { 00113 /// int pass_on( const tag_type & tag, context_type & ) const { return tag % 4; } 00114 /// }; 00115 /// @endcode 00116 /// 00117 /// 00118 /// \attention Pointers as tags are not yet supported by distCnC. It 00119 /// should be possible to implement a serializable wrapper for 00120 /// pointers, though. 00121 /// 00122 /// \attention Global variables are evil and must not be used within 00123 /// the execution scope of steps. 00124 /// 00125 /// \attention "Global" attributes of collections 00126 /// (e.g. size(), iteration, etc.) must not be used while steps are 00127 /// being executed (e.g. within the dynamic scope of step-code). 00128 /// 00129 /// \section dc_run Running with distCnC over sockets 00130 /// On application start-up, CnC checks the environment variable 00131 /// "CNC_SOCKET_HOST". If it is set to a number, it will print a 00132 /// contact string and wait for the given number of clients to 00133 /// connect. Usually this means that clients need to be started 00134 /// "manually" as follows: set "CNC_SOCKET_CLIENT" to the given 00135 /// contact string and launch the same executable on the desired 00136 /// machine. 00137 /// 00138 /// If "CNC_SOCKET_HOST" is is not a number it is interpreted as a 00139 /// name of a script. CnC executes the script twice: First with "-n" 00140 /// it expects the script to return the number of clients it will 00141 /// start. The second invocation is expected to launch the client 00142 /// processes. 00143 /// 00144 /// There is a sample script "misc/start.sh" which you can 00145 /// use. Usually all you need is setting the number of clients and 00146 /// replacing "localhost" with the names of the machines you want the 00147 /// application(-clients) to be started on. It requires password-less 00148 /// login via ssh. It also gives some details of the start-up 00149 /// procedure. For windows, the script "start.bat" does the same, 00150 /// except that it will start the clients on the same machine without 00151 /// ssh or alike. Adjust the script to use your preferred remote login 00152 /// mechanism. 00153 00154 00155 #ifndef _DIST_CNC_ 00156 # define _DIST_CNC_ 00157 #endif 00158 00159 #include <cnc/internal/dist/dist_init.h> 00160 00161 namespace CnC { 00162 namespace Internal { 00163 class void_context; 00164 } 00165 00166 /// To enable remote CnC you must create one such object right after entering main. 00167 /// The object must persist throughout main. 00168 /// All context classes ever used in the program must be referenced as template arguments. 00169 /// All contexts must have all collections they use as members and must be default-constructable. 00170 /// Pointers as tags are not supported by distCnC. 00171 template< class C1, class C2 = Internal::void_context, class C3 = Internal::void_context, 00172 class C4 = Internal::void_context, class C5 = Internal::void_context > 00173 struct /*CNC_API*/ dist_cnc_init : public Internal::dist_init< C1, C2, C3, C4, C5 > 00174 { 00175 dist_cnc_init() : Internal::dist_init< C1, C2, C3, C4, C5 >() {} 00176 }; 00177 00178 } // namespace CnC 00179 00180 #include <cnc/cnc.h> 00181 00182 #endif // __DIST_CNC__H_
1.5.6