diff --git a/job_submit_fx/billing_cost_estimate.lua b/job_submit_fx/billing_cost_estimate.lua index c2ee866..1c39c31 100644 --- a/job_submit_fx/billing_cost_estimate.lua +++ b/job_submit_fx/billing_cost_estimate.lua @@ -1,134 +1,148 @@ -- Function billing_cost_estimate to display job cost -- function billing_cost_estimate (job_desc, cpu_cost, gpu_cost, corespernode, gpuspernode, defaultwtime, defaultpartition, parallel, serial, submit_uid) -- Initializing local variables require('job_submit_fx/scitas_debug.lua') local gputres = nil local gpu = nil local chf = nil local timeinsec = nil local nodetres = job_desc.min_nodes local cputres = job_desc.min_cpus local wtime = job_desc.time_limit local partition = job_desc.partition local ntaskpernode = job_desc.ntasks_per_node local costunit = "cpu" local debugmode = scitas_debug(job_desc) local infisixteen = 65534 local infithirtytwo = 4294967294 local arrayindex = 1 + local freeparts = {'build', 'debug'} + local isfree = 0 if partition == nil then partition = defaultpartition end + -- Free partitions + for i, fpname in ipairs(freeparts) do + if partition == fpname then + isfree = 1 + end + end + + if job_desc.array_inx ~= nil then ak, av = string.match(job_desc.array_inx, "(.*)%-(.*)") if tonumber(ak) ~= nil and tonumber(av) ~= nil then arrayindex = tonumber(av) - tonumber(ak) + 1 end end if job_desc.gres ~= nil then gputres = string.match(job_desc.gres, "gpu.[0-9]+") end -- Convert time in seconds if wtime == nil or wtime == infithirtytwo or wtime == infisixteen then timeinsec = defaultwtime else timeinsec = wtime * 60 end -- Update cost unit if user request GPUs if gputres ~= nil then gk, gv = string.match(gputres, "(.*)%:(.*)") gpu=tonumber(gv) if gpu == nil or gpu < 1 then costunit = nil else costunit = "gpu" end end -- -- User does not define the number of nodes -- if nodetres == infithirtytwo or nodetres == infisixteen or nodetres == nil then if string.match(partition, serial) then node = 1 else node = 0 end else node = nodetres end -- CPUs -- First case: user does not define the number of CPUs -- if cputres == infithirtytwo or cputres == infisixteen or cputres == nil then cpu = corespernode -- -- Second case: user defines the number of CPUs -- else cpu = cputres end -- -- Special cases -- if string.match(partition, parallel) then cpu = corespernode if tonumber(cputres) >= tonumber(corespernode) and node == 0 then if ntaskpernode == infithirtytwo or ntaskpernode == nil or ntaskpernode == infisixteen then node = math.ceil(tonumber(cputres)/tonumber(corespernode)) else node = math.ceil(tonumber(cputres)/tonumber(ntaskpernode)) end end end -- -- Calculating price -- - if costunit == "cpu" then - if cpu == infithirtytwo or node == infithirtytwo then - slurm.log_info("billing::: cannot determine the values to calculate the price") + if isfree == 1 then + chf = 0 + else + if costunit == "cpu" then + if cpu == infithirtytwo or node == infithirtytwo then + slurm.log_info("billing::: cannot determine the values to calculate the price") + else + chf = cpu * node * cpu_cost * timeinsec * arrayindex + end + elseif costunit == "gpu" then + if node == 0 then + node = math.ceil(tonumber(gpu)/tonumber(gpuspernode)) + end + chf = gpu * node * gpu_cost * timeinsec * arrayindex else - chf = cpu * node * cpu_cost * timeinsec * arrayindex + slurm.log_info("billing::: cannot determine the unit type") end - elseif costunit == "gpu" then - if node == 0 then - node = math.ceil(tonumber(gpu)/tonumber(gpuspernode)) - end - chf = gpu * node * gpu_cost * timeinsec * arrayindex - else - slurm.log_info("billing::: cannot determine the unit type") end -- -- Print the price -- -- if chf ~= nil then if debugmode == 1 then slurm.log_user("billing::: cpu: "..cpu) slurm.log_user("billing::: gpu: "..gpu) slurm.log_user("billing::: node: "..node) slurm.log_user("billing::: timeinsec: "..timeinsec) end slurm.log_user("The estimated cost of this job is CHF "..string.format("%.2f",chf)) slurm.log_info("billing::: cost "..submit_uid.."|"..chf) else slurm.log_info("billing::: cannot calculate the price") end end