GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/RenderBackend/backend_jobScript.cpp Lines: 64 71 90.1 %
Date: 2023-10-11 10:52:07 Branches: 133 172 77.3 %

Line Branch Exec Source
1
/***************************************
2
	Auteur : Pierre Aubert
3
	Mail : pierre.aubert@lapp.in2p3.fr
4
	Licence : CeCILL-C
5
****************************************/
6
7
#include <sys/stat.h>
8
#include <sys/types.h>
9
10
#include "backend_getFileName.h"
11
#include "backend_condorSubmit.h"
12
13
#include "backend_jobScript.h"
14
15
///Get the corresponding container of a given scene
16
/**	@param[out] containerFileName : file name of the container
17
 * 	@param scene : Scene we want the container file name
18
 * 	@param renderProject : RenderProject to be used
19
 * 	@return true if the container was found, false otherwise
20
*/
21
2
bool backend_getContainerOfScene(std::string & containerFileName, const Scene & scene, const RenderProject & renderProject){
22
2
	std::map<std::string, Container>::const_iterator it(renderProject.getMapContainer().find(scene.getContainerName()));
23
2
	if(it != renderProject.getMapContainer().end()){
24
2
		containerFileName = it->second.getContainerFilename();
25
2
		return true;
26
	}else{
27
		containerFileName = "";
28
		std::cerr << "backend_getContainerOfScene : cannot found container '"<<scene.getContainerName()<<"' in scene '"<<scene.getName()<<"' (in dir "<<scene.getWorkingDirectory()<<")" << std::endl;
29
		return false;
30
	}
31
}
32
33
///Save the corresponding condor script of the given scene
34
/**	@param fileName : name of the script file to be written
35
 * 	@param scene : Scene to be used
36
 * 	@param renderProject : RenderProject to be used for the script
37
 * 	@return true on success, false otherwise
38
*/
39
2
bool backend_condorScript(const std::string & fileName, const Scene & scene, const RenderProject & renderProject){
40
6
	std::string body(""), containerFileName("");
41
2
	if(!backend_getContainerOfScene(containerFileName, scene, renderProject)){return false;}
42
2
	body += "#!/bin/bash\n\n";
43

2
	body += "INPUT_BLENDER_FILE=\""+scene.getBlenderInputFile()+"\"\n";
44


2
	body += "BLENDER_PROGRAM=\""+renderProject.getApptainerExecutable()+" run --nv --bind .:/data "+renderProject.getComputingCenter().getRemoteContainerDirectory()+"/"+containerFileName+" blender\"\n\n";
45
2
	if(scene.getVecGpuType().size() != 0lu){
46
2
		const std::vector<std::string> & vecExecutableCheckGpu = renderProject.getVecExecutableCheckGpu();
47
6
		for(std::vector<std::string>::const_iterator it(vecExecutableCheckGpu.begin()); it != vecExecutableCheckGpu.end(); ++it){
48
4
			body += (*it) + "\n";
49
		}
50
2
		body += "\n";
51
	}
52
2
	body += "echo \"Used machine is $(uname -a)\"\n";
53
2
	body += "echo \"Selected GPU is _CONDOR_Assignedgpus = '${_CONDOR_Assignedgpus}'\"\n";
54
2
	body += "echo \"Selected GPU is CUDA_VISIBLE_DEVICES = '${CUDA_VISIBLE_DEVICES}'\"\n";
55
56
2
	body += "set -x\n";
57
58

2
	body += "OUTPUT_RENDER_DIR=\""+scene.getOutputRenderDirectory()+"/\"\n";
59
2
	body += "mkdir -p $OUTPUT_RENDER_DIR\n";
60
2
	body += "${BLENDER_PROGRAM} -b /data/${INPUT_BLENDER_FILE} -a";
61
62

2
	body += backend_prefix(scene.getRenderEngine(), " -E ");
63

2
	body += backend_prefix(scene.getBlenderScene(), " -S ");
64


2
	body += " -s "+convertToString(scene.getFirstFrame())+" -e "+convertToString(scene.getLastFrame());
65
2
	if(scene.getStepFrame() != 0){
66

2
		body += " -j " + convertToString(scene.getStepFrame());
67
	}
68
2
	body += " -o \"/Data/$OUTPUT_RENDER_DIR\"";
69

2
	body += backend_prefix(scene.getOutputFormat(), " -F ");
70
2
	body += " -x 1";
71
72
2
	if(scene.getRenderEngine() == "CYCLES"){	//Must be the last option
73

2
		body += backend_prefix(scene.getCycleDevice(), " -- --cycles-device ");
74
	}
75
2
	body += "\n\n";
76
2
	bool b(saveFileContent(fileName, body));
77
	//Make the script executable
78
2
	b &= phoenix_chmod(fileName);
79
2
	return b;
80
}
81
82
///Save the corresponding condor script which submit jobs of the scene of the given scene
83
/**	@param fileName : name of the script file to be written
84
 * 	@param scene : Scene to be used
85
 * 	@param renderProject : RenderProject to be used for the script
86
 * 	@return true on success, false otherwise
87
*/
88
2
bool backend_condorSubmitScript(const std::string & fileName, const Scene & scene, const RenderProject & renderProject){
89
4
	std::string body("");
90
2
	body += "#!/bin/bash\n\n";
91
2
	std::string remoteWorkingDir(renderProject.getComputingCenter().getRemoteWorkingDirectory());
92


2
	body += "cd " + remoteWorkingDir + "/" + getFileName(renderProject.getSourceProjectDir()) + "/" + scene.getWorkingDirectory() + "\n";
93

2
	body += renderProject.getCondorSubmitExecutable() + " .condor/" + backend_getSceneBaseFileName(scene) +  ".submit" + "\n";
94
95
2
	bool b(saveFileContent(fileName, body));
96
	//Make the script executable
97
2
	b &= phoenix_chmod(fileName);
98
4
	return b;
99
}
100
101
102
///Get the status of the given scene
103
/**	@param scene : Scene we want the status
104
 * 	@return true on success, false otherwise
105
*/
106
2
bool backend_createSceneScript(const RenderProject & renderProject, const Scene & scene){
107


2
	std::cout << termCyan() << "Create scripts for Scene"<<termDefault()<<" : '"<<scene.getName()<<"'" << std::endl;
108
2
	bool b(true);
109
6
	std::string condorFileName(backend_getFileName(scene, "submit"));
110
2
	b &= backend_condorSubmit(condorFileName, scene, renderProject.getComputingCenter());
111
6
	std::string condorScript(backend_getFileName(scene, "sh"));
112
2
	b &= backend_condorScript(condorScript, scene, renderProject);
113
4
	std::string mainScript(backend_getFileName(scene, "sh", "call_"));
114
2
	b &= backend_condorSubmitScript(mainScript, scene, renderProject);
115
4
	return b;
116
}
117
118
///Create the script fo the scenes
119
/**	@param[out] isSuccess : true if creating the scripts was a success
120
 * 	@param renderProject : render project to be used
121
 * 	@param wantScript : true if we want to create scripts of scenes
122
 *	@param vecScriptScene : vector of scene names to create their scripts (get all status if empty)
123
 *	@return true if the function was called
124
*/
125
2
bool backend_createSceneScript(bool & isSuccess, const RenderProject & renderProject, bool wantScript, const std::vector<std::string> & vecScriptScene){
126
2
	if(!wantScript){return false;}
127
2
	isSuccess = true;
128
2
	const std::map<std::string, Scene> & mapScene = renderProject.getMapScene();
129
2
	if(vecScriptScene.size() == 0lu){
130
4
		for(std::map<std::string, Scene>::const_iterator it(mapScene.begin()); it != mapScene.end(); ++it){
131
2
			isSuccess &= backend_createSceneScript(renderProject, it->second);
132
		}
133
	}else{
134
		for(std::vector<std::string>::const_iterator it(vecScriptScene.begin()); it != vecScriptScene.end(); ++it){
135
			std::map<std::string, Scene>::const_iterator itFind(mapScene.find(*it));
136
			if(itFind != mapScene.end()){
137
				isSuccess &= backend_createSceneScript(renderProject, itFind->second);
138
			}
139
		}
140
	}
141
2
	return true;
142
}
143
144
145
146
147