diff --git a/app/src/main/java/eu/m724/vastapp/vastai/Utils.kt b/app/src/main/java/eu/m724/vastapp/vastai/StorageCapacityConverters.kt similarity index 63% rename from app/src/main/java/eu/m724/vastapp/vastai/Utils.kt rename to app/src/main/java/eu/m724/vastapp/vastai/StorageCapacityConverters.kt index 3ca177a..fa115b0 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/Utils.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/StorageCapacityConverters.kt @@ -1,17 +1,21 @@ package eu.m724.vastapp.vastai -class Utils { +class StorageCapacityConverters { companion object { fun mbToMib(mb: Number): Double { return mb.toDouble() * 1.048576 } + fun mibToMb(mib: Number): Double { + return mib.toDouble() / 1.048576 + } + fun gbToGib(gb: Number): Double { return gb.toDouble() * 1.073741824 } - fun mibToMb(mib: Number): Double { - return mib.toDouble() / 1.073741824 + fun gibToGb(gib: Number): Double { + return gib.toDouble() / 1.073741824 } } } \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/data/Instance.kt b/app/src/main/java/eu/m724/vastapp/vastai/data/Instance.kt index 288b244..5dab4d4 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/data/Instance.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/data/Instance.kt @@ -7,15 +7,15 @@ import org.json.JSONObject * units are in decimal bytes that is 1000 MB GB */ data class Instance( - val id: Int, val machine: Machine, + val pricing: Pricing, - /** memory available in instance in MB */ - val instanceMemoryMb: Int, - /** cpu cores available in instance like 6.1 */ + /** memory assigned to the instance in MB */ + val instanceMemory: Int, + /** cpu cores assigned to the instance like 6.1 */ val instanceCpuCores: Double, - /** how many (same) gpus the instance has*/ - val instanceNumGpus: Int, + /** gpus assigned to the instance */ + val instanceGpus: Int, /** "Deep Learning Performance", it's very specific like 15.679831880208411 */ val dlPerf: Double, @@ -24,29 +24,19 @@ data class Instance( * at least I think because it's recent and unavailable machines don't have that */ val startDate: Long, /** when instance will expire as unix seconds, like 1861891577 */ - val endDate: Long, - - /** is the instance available for rental */ - val available: Boolean + val endDate: Long ) { companion object { fun fromJson(json: JSONObject): Instance { return Instance( - json.getInt("id"), Machine.fromJson(json), - json.getInt("cpu_ram"), + Pricing.fromJson(json), + (json.getInt("cpu_ram") / json.getDouble("gpu_frac")).toInt(), json.getDouble("cpu_cores_effective"), json.getInt("num_gpus"), json.getDouble("dlperf"), - json.getDouble("dph_base"), - json.getDouble("storage_cost"), - json.getDouble("inet_down_cost"), - json.getDouble("inet_up_cost"), - json.getBoolean("is_bid"), - json.getDouble("min_bid"), json.getDouble("start_date").toLong(), - json.getLong("end_date"), - json.getBoolean("rentable") + json.getDouble("end_date").toLong() ) } } diff --git a/app/src/main/java/eu/m724/vastapp/vastai/data/Machine.kt b/app/src/main/java/eu/m724/vastapp/vastai/data/Machine.kt index ad0d39a..9161de3 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/data/Machine.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/data/Machine.kt @@ -1,6 +1,6 @@ package eu.m724.vastapp.vastai.data -import eu.m724.vastapp.vastai.Utils +import eu.m724.vastapp.vastai.StorageCapacityConverters import org.json.JSONObject /** @@ -8,69 +8,23 @@ import org.json.JSONObject * that is the machine with physical resources */ data class Machine( - val id: Int, + val machineId: Int, /** machine host's id, that is the account the machine is listed by */ val hostId: Int, + val cpu: CPU, + val gpu: GPU, + val disk: Disk, + val network: Network, + /** motherboard name, like X99 or TUF GAMING X570 */ val motherboardName: String, /** machine ram in MB */ - val memory: Double, - - /** cpu architecture, like amd64 */ - val cpuArch: String, - /** machine cpu cores like 12 */ - val cpuCores: Int, - /** readable cpu name like xeon something */ - val cpuName: String, - /** only when viewing a not rented instance */ - val cpuGhz: Double, - - /** disk bandwidth in MB/s (TODO find out) like 1225.1 */ - val diskBandwidth: Double, - /** disk name, like nvme (literally) or a model like SPCC M.2 PCIe SSD */ - val diskName: String, - /** available disk space on host in GB (TODO find out) like 95.833336 */ - val diskSpace: Double, - - /** pcie gpu lanes like 8 */ - val gpuLanes: Int, - /** vram bandwidth in GB/s (TODO find out) like 3518 */ - val gpuMemoryBandwidth: Double, - /** gpu name like RTX 4090 */ - val gpuName: String, - /** vram in MB */ - val gpuMemoryMb: Int, - - /** max cuda version like 12.2 */ - val cudaMaxGood: Double, - /** nvidia driver version like 545.23.06 */ - val driverVersion: String, - /** not sure, changes with gpu series, like 860 for rtx 3000 series*/ - val computeCap: Int, - - /** pcie version like 3.0 or 4.0 */ - val pcieGen: Double, - /** pcie bandwidth in GB/s (TODO find out) like 11.7 */ - val pcieBandwidth: Double, - - /** download speed in Mbps */ - val inetDownSpeedMbps: Double, - /** upload speed in Mbps */ - val inetUpSpeedMbps: Double, - /** amount of open ports like 99 */ - val directPortCount: Int, - /** public ip address of the machine, like 192.0.2.1 */ - val publicAddress: String, - /** self explanatory but not sure if matters */ - val isStaticAddress: Boolean, - /** formatted as City, CC like Quebec, CA */ - val geolocation: String, + val memory: Int, /** reliability of the machine 0-1 */ val reliability: Double, - /** how is the machine hosted, 0 normal, 1 datacenter */ - val hostingType: Int, + val hostingClass: HostingClass, val verification: MachineVerification ) { companion object { @@ -78,38 +32,110 @@ data class Machine( return Machine( json.getInt("machine_id"), json.getInt("host_id"), + CPU( + json.getString("cpu_name"), + json.getString("cpu_arch"), + json.getInt("cpu_cores"), + (json.opt("cpu_ghz") ?: null) as Double?, + ), + GPU( + json.getString("gpu_name"), + json.getDouble("total_flops"), + StorageCapacityConverters.mibToMb(json.getInt("gpu_ram")).toInt(), + json.getDouble("gpu_mem_bw"), + json.getInt("gpu_lanes"), + json.getDouble("pci_gen"), + json.getDouble("pcie_bw"), + json.getDouble("cuda_max_good"), + json.getString("driver_version"), + json.getInt("compute_cap") + ), + Disk( + json.getString("disk_name"), + json.getDouble("disk_bw") + ), + Network( + json.getDouble("inet_down"), + json.getDouble("inet_up"), + json.getInt("direct_port_count"), + json.getString("public_ipaddr"), + json.getBoolean("static_ip"), + json.getString("geolocation") + ), json.getString("mobo_name"), - json.getInt("cpu_ram") / json.getDouble("gpu_frac"), - json.getString("cpu_arch"), - json.getInt("cpu_cores"), - json.getString("cpu_name"), - json.optDouble("cpu_ghz", -1.0), - json.getDouble("disk_bw"), - json.getString("disk_name"), - json.getDouble("disk_space"), - json.getInt("gpu_lanes"), - json.getDouble("gpu_mem_bw"), - json.getString("gpu_name"), - Utils.mibToMb(json.getInt("gpu_ram")).toInt(), - json.getDouble("cuda_max_good"), - json.getString("driver_version"), - json.getInt("compute_cap"), - json.getDouble("pci_gen"), - json.getDouble("pcie_bw"), - json.getDouble("inet_down"), - json.getDouble("inet_up"), - json.getInt("direct_port_count"), - json.getString("public_ipaddr"), - json.getBoolean("static_ip"), - json.getString("geolocation"), + json.getInt("cpu_ram"), json.getDouble("reliability2"), - json.getInt("hostingType"), + HostingClass.entries.getOrElse(json.getInt("hostingType")) { HostingClass.PRIVATE }, MachineVerification.fromString(json.getString("verification")) ) } } } +data class CPU( + /** readable cpu model name like xeon something */ + val model: String, + /** cpu architecture, like amd64 */ + val architecture: String, + /** machine cpu cores like 12 */ + val cores: Int, + /** cpu frequency in GHz + * null if viewing a rented instance */ + val frequency: Double? +) + +data class Disk( + /** disk label, like nvme (literally) or a model like SPCC M.2 PCIe SSD */ + val model: String, + /** disk "bandwidth" in MB/s (TODO find out mb or mib?) + * bandwidth is the maximum capacity of the channel, while speed is the actual rate at which data is being transferred + * - llama */ + val diskSpeed: Double +) + +data class Network( + /** download speed in Mbps */ + val downloadSpeed: Double, + /** upload speed in Mbps */ + val uploadSpeed: Double, + /** how many forwarded ports */ + val portCount: Int, + /** public ip address for inbound connections */ + val publicAddress: String, + val isAddressStatic: Boolean, + /** formatted as City, CC like Quebec, CA */ + val geolocation: String, +) + +data class GPU( + /** model without brand name */ + val model: String, + /** teraflops **/ + val tFlops: Double, + /** vram in MB per gpu */ + val memoryCapacity: Int, + /** vram bandwidth in GB/s (TODO find out) */ + val memoryBandwidth: Double, + /** pcie gpu lanes like 8 */ + val pcieLanes: Int, + /** pcie version like 3.0 or 4.0 */ + val pcieGen: Double, + /** pcie bandwidth in GB/s (TODO find out) */ + val pcieBandwidth: Double, + + /** cuda version like 12.2 */ + val cudaVersion: Double, + /** nvidia driver version like 545.23.06 */ + val driverVersion: String, + /** not sure, changes with gpu series, like 860 for rtx 3000 series + * TODO should it even be here? */ + val computeCap: Int +) + +enum class HostingClass { + PRIVATE, DATACENTER +} + enum class MachineVerification { VERIFIED, UNVERIFIED, VERIFICATION_REMOVED; diff --git a/app/src/main/java/eu/m724/vastapp/vastai/data/MarketInstance.kt b/app/src/main/java/eu/m724/vastapp/vastai/data/MarketInstance.kt new file mode 100644 index 0000000..41d32b8 --- /dev/null +++ b/app/src/main/java/eu/m724/vastapp/vastai/data/MarketInstance.kt @@ -0,0 +1,28 @@ +package eu.m724.vastapp.vastai.data + +import org.json.JSONObject + +data class MarketInstance( + /** id of the market instance, it changes after renting */ + val listingId: Int, + val instance: Instance, + + /** machine disk space in GB */ + val diskSpace: Double, + /** if the instance is rented by you */ + val owned: Boolean, + /** is the instance available for rental (rentable) */ + val available: Boolean +) { + companion object { + fun fromJson(json: JSONObject): MarketInstance { + return MarketInstance( + json.getInt("id"), + Instance.fromJson(json), + json.getDouble("disk_space"), + json.getBoolean("owned"), + json.getBoolean("rentable") + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/data/Pricing.kt b/app/src/main/java/eu/m724/vastapp/vastai/data/Pricing.kt index edebac3..5411c2e 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/data/Pricing.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/data/Pricing.kt @@ -1,5 +1,13 @@ package eu.m724.vastapp.vastai.data +import org.json.JSONObject + +/* +price is probably the correct word but I'm not sure so I leave it as it is in the api + +Cost is what it takes to make something, while Price is what you charge for it. +- llama + */ data class Pricing( /** if you're bidding this instance, always false in marketplace (or not?) */ val isBid: Boolean, @@ -9,12 +17,26 @@ data class Pricing( /** dollars per hour excluding storage costs */ val dphBase: Double, - /** storage cost 1 GB / 30 days (720 hours) - * to get hourly, divide it by 720 and multiply by GBs TODO remove this comment */ - /** storage cost GB/hr */ + /** dollars per hour including storage costs */ + val dphTotal: Double?, + /** storage cost $/GB*hr */ val storageCost: Double, /** dollars per 1 GB of download (on site it shows TB as 1024 so TODO gb or gib?) **/ val downloadCost: Double, /** dollars per 1 GB of upload (on site it shows TB as 1024) **/ val uploadCost: Double, -) \ No newline at end of file +) { + companion object { + fun fromJson(json: JSONObject): Pricing { + return Pricing( + json.getBoolean("is_bid"), + json.getDouble("min_bid"), + json.getDouble("dph_base"), + json.getDouble("dph_total"), + json.getDouble("storage_cost") / 720, + json.getDouble("inet_down_cost"), + json.getDouble("inet_up_cost") + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/data/RentedInstance.kt b/app/src/main/java/eu/m724/vastapp/vastai/data/RentedInstance.kt index 8918057..c822d67 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/data/RentedInstance.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/data/RentedInstance.kt @@ -1,17 +1,17 @@ package eu.m724.vastapp.vastai.data -import android.net.InetAddresses -import java.net.InetAddress +import eu.m724.vastapp.vastai.StorageCapacityConverters +import org.json.JSONObject data class RentedInstance( + /** the rental id */ + val rentalId: Int, val instance: Instance, - /** the rental id, apparently not rented id is different */ - val rentalId: Int, - /** rented disk space in MB */ - val diskSpace: Int, - /** disk usage in MB */ - val diskUsage: Int, + /** rented disk space in GB (TODO GB?) */ + val diskSpace: Double, + /** disk usage in GB (TODO GB?) */ + val diskUsage: Double, /** vram usage in MB */ val vramUsage: Int, /** ram usage in MB */ @@ -36,10 +36,33 @@ data class RentedInstance( /** the docker image that runs on the instance */ val image: String, - /** label set by user */ - val label: String, + /** label set by user, null if not set */ + val label: String?, /** local ip addresses? * I think if you have another instance on the same machine you can use it */ - val localIpAddresses: List -) \ No newline at end of file + val localIpAddresses: List +) { + companion object { + fun fromJson(json: JSONObject): RentedInstance { + return RentedInstance( + json.getInt("id"), + Instance.fromJson(json), + json.getDouble("disk_space"), + json.getDouble("disk_util"), + (StorageCapacityConverters.gibToGb(json.getDouble("vmem_usage")) / 1000).toInt(), + (json.getDouble("mem_usage") / 1000).toInt(), + json.getDouble("gpu_util") / 100, + json.getDouble("cpu_util") / 100, + json.getDouble("gpu_temp"), + json.getDouble("inet_down_billed").toInt(), + json.getDouble("inet_up_billed").toInt(), + json.getString("ssh_host"), + json.getInt("ssh_port"), + json.getString("image_uuid"), + json.optString("label").takeIf { it.isNotBlank() }, + json.getString("local_ipaddrs").split(" ").filterNot { it == "\n" } + ) + } + } +} \ No newline at end of file diff --git a/dev_assets/rented exclusive keys b/dev_assets/rented exclusive keys index f795c07..995532d 100644 --- a/dev_assets/rented exclusive keys +++ b/dev_assets/rented exclusive keys @@ -19,7 +19,7 @@ "image_runtype": "str", // "ssh" if has ssh, "ssh_direc" if can connect directly, "ssh_proxy" if can connect via proxy. other types probably exist "extra_env": "list", // docker arguments and environment variables, set in iamge config "onstart": "str", // script that runs on start, set in iamge config - "label": "NoneType", // label set by user + "label": "str", // label set by user "jupyter_token": "str", "status_msg": "str", // status but longer "gpu_util": "float", // 0 - 100