1 /* $Id: test_gridclient_stress.cpp 574016 2018-11-05 16:55:15Z sadyrovr $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors: Maxim Didenko
27 *
28 * File Description:
29 *
30 */
31
32 #include <ncbi_pch.hpp>
33
34 #include <connect/services/grid_client.hpp>
35 #include <connect/services/grid_client_app.hpp>
36 #include <connect/services/grid_app_version_info.hpp>
37
38 #include <corelib/ncbiapp.hpp>
39 #include <corelib/ncbimisc.hpp>
40 #include <corelib/ncbi_system.hpp>
41
42 #include <math.h>
43 #include <algorithm>
44
45 #define GRID_APP_NAME "test_gridclient_stress"
46
47 USING_NCBI_SCOPE;
48
49 class CGridClientTestApp : public CGridClientApp
50 {
51 public:
52 virtual void Init(void);
53 virtual int Run(void);
54 virtual string GetProgramVersion(void) const;
55
UseProgressMessage() const56 virtual bool UseProgressMessage() const
57 {
58 return false;
59 }
60 };
61
GetProgramVersion(void) const62 string CGridClientTestApp::GetProgramVersion(void) const
63 {
64 return GRID_APP_VERSION_INFO;
65 }
66
67
Init(void)68 void CGridClientTestApp::Init(void)
69 {
70 CGridClientApp::Init();
71
72 // Create command-line argument descriptions class
73 unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
74
75 // Specify USAGE context
76 arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
77 "Grid client sample");
78
79 arg_desc->AddOptionalKey("jcount",
80 "jcount",
81 "Number of jobs to submit",
82 CArgDescriptions::eInteger);
83
84 arg_desc->AddOptionalKey("vsize",
85 "vsize",
86 "Size of the test vector",
87 CArgDescriptions::eInteger);
88
89
90 // Setup arg.descriptions for this application
91 SetupArgDescriptions(arg_desc.release());
92 }
93
Run(void)94 int CGridClientTestApp::Run(void)
95 {
96 const CArgs& args = GetArgs();
97
98 unsigned jcount = 5;
99 int vsize = 10000;
100 if (args["jcount"]) {
101 jcount = args["jcount"].AsInteger();
102 }
103 if (args["vsize"]) {
104 vsize = args["vsize"].AsInteger();
105 }
106
107 CNetScheduleAPI::EJobStatus status;
108 NcbiCout << "Submit " << jcount << " jobs..." << NcbiEndl;
109
110 CGridClient& grid_client = GetGridClient();
111
112 string input1 = "Hello ";
113 typedef map<string, vector<double>* > TJobs;
114 TJobs jobs;
115 for (unsigned i = 0; i < jcount; ++i) {
116 string ns_key;
117 vector<double>* dvec = new vector<double>;
118 CNcbiOstream& os = grid_client.GetOStream();
119 os << "doubles " << vsize << ' ';
120 srand( (unsigned)time( NULL ) );
121 for (int j = 0; j < vsize; ++j) {
122 double d = rand()*0.2;
123 os << d << ' ';
124 dvec->push_back(d);
125 }
126 string job_key = grid_client.Submit();
127 sort(dvec->begin(),dvec->end());
128 jobs[job_key] = dvec;
129
130 if (i % 1000 == 0) {
131 NcbiCout << "." << flush;
132 }
133 }
134 NcbiCout << NcbiEndl << "Done." << NcbiEndl;
135
136 NcbiCout << "Waiting for jobs..." << jobs.size() << NcbiEndl;
137 unsigned cnt = 0;
138 SleepMilliSec(100);
139
140 while (jobs.size()) {
141 NON_CONST_ITERATE(TJobs, it, jobs) {
142 const string& jk = it->first;
143 grid_client.SetJobKey(jk);
144 vector<double>* dvec = it->second;
145
146 status = grid_client.GetStatus();
147
148 if (status == CNetScheduleAPI::eDone) {
149 CNcbiIstream& is = grid_client.GetIStream();
150 if (!is.good()) {
151 LOG_POST("Input stream error while reading the "
152 "size of the resulting vector");
153 break;
154 }
155 int count;
156 is >> count;
157 vector<double> resvec;
158 for (int i = 0; i < count; ++i) {
159 if (!is.good()) {
160 LOG_POST( "Input stream error. Index : " << i );
161 break;
162 }
163 double d;
164 is >> d;
165 resvec.push_back(d);
166 }
167 if (resvec.size() == dvec->size()) {
168 for(size_t i = 0; i < resvec.size(); ++i) {
169 //cout << (*dvec)[i] << " --- " << resvec[i] << "; ";
170 if( fabs((*dvec)[i] - resvec[i])/resvec[i] > 0.001 ) {
171 LOG_POST( "Test failed! Wrong vector element. Difference is "
172 << fabs((*dvec)[i] - resvec[i]));
173 break;
174 }
175 }
176 cout << endl;
177 }
178 else {
179 LOG_POST( "Test failed! Wrong vector size." );
180 }
181 LOG_POST( "Job " << jk << " done." );
182 delete dvec;
183 jobs.erase(it);
184 ++cnt;
185 break;
186 }
187 else if (status == CNetScheduleAPI::eFailed) {
188 LOG_POST( "Job " << jk << " failed : " << grid_client.GetErrorMessage() );
189 delete dvec;
190 jobs.erase(it);
191 ++cnt;
192 break;
193 }
194
195 else if (status == CNetScheduleAPI::eCanceled) {
196 NcbiCerr << "Job " << jk << " is canceled." << NcbiEndl;
197 delete dvec;
198 jobs.erase(it);
199 ++cnt;
200 break;
201 }
202
203 ++cnt;
204 if (cnt % 1000 == 0) {
205 NcbiCout << "Waiting for "
206 << jobs.size()
207 << " jobs."
208 << NcbiEndl;
209 // it is necessary to give system a rest periodically
210 SleepMilliSec(2000);
211 // check status of only first 1000 jobs
212 // since the JS queue execution priority is FIFO
213 break;
214 }
215 }
216
217 }
218 return 0;
219 }
220
221
main(int argc,const char * argv[])222 int main(int argc, const char* argv[])
223 {
224 GRID_APP_CHECK_VERSION_ARGS();
225
226 return CGridClientTestApp().AppMain(argc, argv, 0, eDS_Default,
227 GRID_APP_NAME ".ini");
228 }
229