22 addNumberWithUnits ,
33 compareNumberWithUnits ,
44 convertBinarySizeUnit ,
5+ subNumberWihUnits ,
56} from '../helper' ;
67import { useSuspendedBackendaiClient , useUpdatableState } from '../hooks' ;
78import { useResourceSlotsDetails } from '../hooks/backendai' ;
@@ -15,6 +16,8 @@ import {
1516} from '../hooks/useResourceLimitAndRemaining' ;
1617import AgentSelect from './AgentSelect' ;
1718import BAISelect from './BAISelect' ;
19+ import DynamicInputNumber from './DynamicStepInputNumber' ;
20+ import DynamicUnitInputNumber from './DynamicUnitInputNumber' ;
1821import DynamicUnitInputNumberWithSlider from './DynamicUnitInputNumberWithSlider' ;
1922import Flex from './Flex' ;
2023// import FormItemControl from './FormItemControl';
@@ -23,6 +26,7 @@ import {
2326 ImageEnvironmentFormInput ,
2427} from './ImageEnvironmentSelectFormItems' ;
2528import InputNumberWithSlider from './InputNumberWithSlider' ;
29+ import QuestionIconWithTooltip from './QuestionIconWithTooltip' ;
2630import ResourceGroupSelect from './ResourceGroupSelect' ;
2731import ResourcePresetSelect from './ResourcePresetSelect' ;
2832import { ResourceAllocationFormItemsQuery } from './__generated__/ResourceAllocationFormItemsQuery.graphql' ;
@@ -31,14 +35,18 @@ import {
3135 Button ,
3236 Card ,
3337 Col ,
38+ ConfigProvider ,
3439 Divider ,
3540 Form ,
41+ InputNumber ,
3642 Radio ,
3743 Row ,
44+ Slider ,
3845 Switch ,
3946 theme ,
4047} from 'antd' ;
4148import graphql from 'babel-plugin-relay/macro' ;
49+ import { log } from 'console' ;
4250import _ from 'lodash' ;
4351import React , { Suspense , useEffect , useMemo , useTransition } from 'react' ;
4452import { Trans , useTranslation } from 'react-i18next' ;
@@ -838,8 +846,246 @@ const ResourceAllocationFormItems: React.FC<
838846 ) ;
839847 } }
840848 </ Form . Item >
849+ < Form . Item
850+ noStyle
851+ dependencies = { [
852+ [ 'resource' , 'mem' ] ,
853+ [ 'resource' , 'shmem' ] ,
854+ [ 'enabledAutomaticShmem' ] ,
855+ ] }
856+ >
857+ { ( { getFieldValue } ) => {
858+ const mem = getFieldValue ( [ 'resource' , 'mem' ] ) ;
859+ const shmem = getFieldValue ( [ 'resource' , 'shmem' ] ) ;
860+ const memUnitResult = convertBinarySizeUnit (
861+ mem ,
862+ 'auto' ,
863+ 2 ,
864+ ) ;
865+ const shmemUnitResult = convertBinarySizeUnit (
866+ shmem ,
867+ 'auto' ,
868+ 2 ,
869+ ) ;
870+ const appMemUnitResult = convertBinarySizeUnit (
871+ ( convertBinarySizeUnit ( mem , 'b' ) ?. number || 0 ) -
872+ ( convertBinarySizeUnit ( shmem , 'b' ) ?. number || 0 ) +
873+ 'b' ,
874+ memUnitResult ?. unit ,
875+ ) ;
876+ const isAutoShmem = getFieldValue (
877+ 'enabledAutomaticShmem' ,
878+ ) ;
879+
880+ return (
881+ < Flex direction = "column" align = "stretch" >
882+ { /* <Form.Item name={['resource', 'shmem']}> */ }
883+ < Flex direction = "row" gap = { 'sm' } >
884+ < ConfigProvider
885+ theme = { {
886+ components : {
887+ Slider : {
888+ railBg : token . colorWarning ,
889+ railHoverBg : token . colorWarning ,
890+ trackBg : token . colorSuccess ,
891+ trackHoverBg : token . colorSuccess ,
892+ railSize : token . fontSize ,
893+ } ,
894+ } ,
895+ } }
896+ >
897+ < Slider
898+ style = { {
899+ flex : 1 ,
900+ margin : 0 ,
901+ cursor : 'default' ,
902+ } }
903+ styles = { {
904+ handle : {
905+ // display: isAutoShmem ? 'none' : undefined,
906+ display : 'none' ,
907+ } ,
908+ } }
909+ value = { appMemUnitResult ?. number }
910+ max = { memUnitResult ?. number }
911+ />
912+ </ ConfigProvider >
913+ </ Flex >
914+ { /* </Form.Item> */ }
915+ < Flex direction = "row" gap = { 'xxs' } justify = "between" >
916+ < Flex gap = { 'xxs' } >
917+ < div
918+ style = { {
919+ height : token . fontSize ,
920+ width : token . fontSize ,
921+ backgroundColor : token . colorSuccess ,
922+ } }
923+ > </ div >
924+ Application MEM { appMemUnitResult ?. numberUnit }
925+ </ Flex >
926+ < Flex gap = { 'xxs' } >
927+ < div
928+ style = { {
929+ height : token . fontSize ,
930+ width : token . fontSize ,
931+ backgroundColor : token . colorWarning ,
932+ } }
933+ > </ div >
841934
842- < Flex direction = "column" gap = { 'xxs' } align = "start" >
935+ { getFieldValue ( 'enabledAutomaticShmem' ) ? (
936+ `SHMEM ${ shmemUnitResult ?. numberUnit } `
937+ ) : (
938+ < Form . Item
939+ noStyle
940+ name = { [ 'resource' , 'shmem' ] }
941+ // initialValue={'0g'}
942+ // label={t('session.launcher.SharedMemory')}
943+ hidden = { form . getFieldValue (
944+ 'enabledAutomaticShmem' ,
945+ ) }
946+ tooltip = {
947+ < Trans
948+ i18nKey = {
949+ 'session.launcher.DescSharedMemory'
950+ }
951+ />
952+ }
953+ dependencies = { [ [ 'resource' , 'mem' ] ] }
954+ rules = { [
955+ {
956+ required : true ,
957+ } ,
958+ { } ,
959+ {
960+ warningOnly : true ,
961+ validator : async (
962+ rule ,
963+ value : string ,
964+ ) => {
965+ const applicationMem =
966+ appMemUnitResult ?. numberUnit ;
967+ const shmem = value ;
968+
969+ if (
970+ _ . isEmpty ( applicationMem ) ||
971+ _ . isEmpty ( shmem )
972+ ) {
973+ return Promise . resolve ( ) ;
974+ }
975+
976+ if (
977+ ( convertBinarySizeUnit (
978+ applicationMem ,
979+ 'M' ,
980+ ) ?. number || 0 ) <
981+ ( convertBinarySizeUnit ( shmem , 'M' )
982+ ?. number || 0 ) *
983+ 2
984+ ) {
985+ throw '공유 메모리는 Application MEM의 절반 이하가 권장됩니다.' ;
986+ } else {
987+ return Promise . resolve ( ) ;
988+ }
989+ } ,
990+ } ,
991+
992+ {
993+ validator : async (
994+ rule ,
995+ value : string ,
996+ ) => {
997+ if (
998+ _ . isEmpty (
999+ getFieldValue ( 'resource' ) ?. mem ,
1000+ ) ||
1001+ _ . isEmpty ( value ) ||
1002+ compareNumberWithUnits (
1003+ getFieldValue ( 'resource' ) ?. mem ,
1004+ value ,
1005+ ) >= 0
1006+ ) {
1007+ return Promise . resolve ( ) ;
1008+ } else {
1009+ throw t (
1010+ 'resourcePreset.SHMEMShouldBeSmallerThanMemory' ,
1011+ ) ;
1012+ }
1013+ } ,
1014+ } ,
1015+ ] }
1016+ >
1017+ < DynamicUnitInputNumber
1018+ // shmem max is mem max
1019+ // min={resourceLimits.shmem?.min}
1020+ min = { resourceLimits . shmem ?. min }
1021+ size = "small"
1022+ // max={resourceLimits.mem?.max || '0g'}
1023+ addonBefore = { 'SHM' }
1024+ max = {
1025+ form . getFieldValue ( [
1026+ 'resource' ,
1027+ 'mem' ,
1028+ ] ) || '0g'
1029+ }
1030+ style = { {
1031+ width : 200 ,
1032+ } }
1033+ onChange = { ( ) => {
1034+ form . setFieldValue (
1035+ 'allocationPreset' ,
1036+ 'custom' ,
1037+ ) ;
1038+ } }
1039+ />
1040+ </ Form . Item >
1041+ // <DynamicUnitInputNumber
1042+ // value={shmem}
1043+ // onChange={() => {}}
1044+ // size="small"
1045+ // variant="outlined"
1046+ // addonBefore={'SHMEM'}
1047+ // style={{
1048+ // width: 200,
1049+ // }}
1050+ // />
1051+ ) }
1052+ < Flex direction = "row" gap = "xs" >
1053+ < Form . Item
1054+ noStyle
1055+ name = { 'enabledAutomaticShmem' }
1056+ valuePropName = "checked"
1057+ >
1058+ < Switch
1059+ size = "small"
1060+ title = "auto"
1061+ checkedChildren = { 'AUTO' }
1062+ unCheckedChildren = { 'MANUAL' }
1063+ onChange = { ( checked ) => {
1064+ if ( checked ) {
1065+ runShmemAutomationRule (
1066+ form . getFieldValue ( [
1067+ 'resource' ,
1068+ 'mem' ,
1069+ ] ) || '0g' ,
1070+ ) ;
1071+ }
1072+ form . setFieldValue (
1073+ 'allocationPreset' ,
1074+ 'custom' ,
1075+ ) ;
1076+ } }
1077+ />
1078+ </ Form . Item >
1079+ < QuestionIconWithTooltip title = "할당한 메모리 내에서 공유 메모리로 사용할 크기를 자동 선택하거나 수동으로 입력할 수 있습니다." />
1080+ </ Flex >
1081+ </ Flex >
1082+ </ Flex >
1083+ </ Flex >
1084+ ) ;
1085+ } }
1086+ </ Form . Item >
1087+
1088+ { /* <Flex direction="column" gap={'xxs'} align="start">
8431089 <Flex direction="row" gap={'xs'}>
8441090 {t('session.launcher.EnableAutomaticMiniumShmem')}{' '}
8451091 <Form.Item
@@ -870,6 +1116,7 @@ const ResourceAllocationFormItems: React.FC<
8701116 }
8711117 >
8721118 {() => {
1119+ return null;
8731120 return (
8741121 <Form.Item
8751122 noStyle
@@ -934,9 +1181,10 @@ const ResourceAllocationFormItems: React.FC<
9341181 );
9351182 }}
9361183 </Form.Item>
937- </ Flex >
1184+ </Flex> */ }
9381185 </ Form . Item >
9391186 ) }
1187+
9401188 < Form . Item
9411189 noStyle
9421190 shouldUpdate = { ( prev , next ) => {
0 commit comments